From fe67ba10a6a20c797ccc264f769a72f3a7bf9e27 Mon Sep 17 00:00:00 2001 From: Michael Angelos Simos Date: Thu, 7 Feb 2019 17:39:52 +0200 Subject: [PATCH 01/23] Update balena link --- docker-for-mac/multi-arch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-for-mac/multi-arch.md b/docker-for-mac/multi-arch.md index 423996f994..5fb31a6fa3 100644 --- a/docker-for-mac/multi-arch.md +++ b/docker-for-mac/multi-arch.md @@ -15,7 +15,7 @@ This does not require any special configuration in the container itself as it us qemu-static from the Docker for Mac VM. -You can run an ARM container, like the +You can run an ARM container, like the balena arm builds: ``` From 2680b26b4b6b096c85d71019937655d7831c4125 Mon Sep 17 00:00:00 2001 From: Maria Bermudez Date: Wed, 13 Feb 2019 09:55:39 -0800 Subject: [PATCH 02/23] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 953f6c916e..d700366c81 100644 --- a/README.md +++ b/README.md @@ -323,9 +323,9 @@ Supported documentation includes the current version plus the previous five vers If you are using a version of the documentation that is no longer supported, which means that the version number is not listed in the site dropdown list, you can still access that documentation in the following ways: -- By entering your version number in the branch selection list for this repo +- By entering your version number and selecting it from the branch selection list for this repo - By directly accessing the Github URL for your version. For example, https://github.com/docker/docker.github.io/tree/v1.9 for `v1.9` -- By running a container of the specific [tag for your documentation version](https://cloud.docker.com/u/docs/repository/docker/docs/docker.github.io/general#read-these-docs-offline){: target="_blank"} +- By running a container of the specific [tag for your documentation version](https://cloud.docker.com/u/docs/repository/docker/docs/docker.github.io/general#read-these-docs-offline) in Docker Hub. For example, run the following to access `v1.9`: ```bash From f5ab105cce2b33755d39f3d9cc2716b2058107d1 Mon Sep 17 00:00:00 2001 From: Maria Bermudez Date: Wed, 13 Feb 2019 10:16:54 -0800 Subject: [PATCH 03/23] Incorporate suggested updates --- docker-for-mac/multi-arch.md | 60 ++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/docker-for-mac/multi-arch.md b/docker-for-mac/multi-arch.md index 5fb31a6fa3..bb248844e3 100644 --- a/docker-for-mac/multi-arch.md +++ b/docker-for-mac/multi-arch.md @@ -6,29 +6,51 @@ redirect_from: title: Leverage multi-CPU architecture support notoc: true --- +Docker images can support multiple architectures, which means that a single +image may contain variants for different architectures, and sometimes for different +operating systems, such as Windows. -Docker Desktop for Mac provides `binfmt_misc` multi architecture support, so you can run -containers for different Linux architectures, such as `arm`, `mips`, `ppc64le`, -and even `s390x`. +When running an image with multi-architecture support, `docker` will +automatically select an image variant which matches your OS and architecture. + +Most of the official images on Docker Hub provide a [variety of architectures](https://github.com/docker-library/official-images#architectures-other-than-amd64). +For example, the `busybox` image supports `amd64`, `arm32v5`, `arm32v6`, +`arm32v7`, `arm64v8`, `i386`, `ppc64le`, and `s390x`. When running this image +on an `x86_64` / `amd64` machine, the `x86_64` variant will be pulled and run, +which can be seen from the output of the `uname -a` command that's run inside +the container: + +```bash +$ docker run busybox uname -a + +Linux 82ef1a0c07a2 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64 GNU/Linux +``` + +**Docker Desktop for Mac** provides `binfmt_misc` multi-architecture support, +which means you can run containers for different Linux architectures +such as `arm`, `mips`, `ppc64le`, and even `s390x`. This does not require any special configuration in the container itself as it uses -qemu-static from the Docker for -Mac VM. +qemu-static from the **Docker for +Mac VM**. Because of this, you can run an ARM container, like the `arm32v7` or `ppc64le` +variants of the busybox image: -You can run an ARM container, like the -balena arm builds: - -``` -$ docker run balenalib/armv7hf-debian uname -a - -Linux 3d3ffca44f6e 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 armv7l GNU/Linux - -$ docker run justincormack/ppc64le-debian uname -a - -Linux edd13885f316 4.1.12 #1 SMP Tue Jan 12 10:51:00 UTC 2016 ppc64le GNU/Linux +### arm32v7 variant +```bash +$ docker run arm32v7/busybox uname -a +Linux 9e3873123d09 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 armv7l GNU/Linux ``` -Multi architecture support makes it easy to build -multi architecture Docker images or experiment with ARM images and binaries -from your Mac. +### ppc64le variant +```bash +$ docker run ppc64le/busybox uname -a + +Linux 57a073cc4f10 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 ppc64le GNU/Linux +``` + +Notice that this time, the `uname -a` output shows `armv7l` and +`ppc64le` respectively. + +Multi-architecture support makes it easy to build multi-architecture Docker images or experiment with ARM images and binaries from your Mac. + From d93d4caf8a0bef4c3a4cce2e17c30ae9795259ef Mon Sep 17 00:00:00 2001 From: paigehargrave Date: Wed, 13 Feb 2019 14:15:10 -0500 Subject: [PATCH 04/23] Update IP address conflict info --- ee/ucp/admin/install/plan-installation.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ee/ucp/admin/install/plan-installation.md b/ee/ucp/admin/install/plan-installation.md index 6a3f3195d8..0426126fd2 100644 --- a/ee/ucp/admin/install/plan-installation.md +++ b/ee/ucp/admin/install/plan-installation.md @@ -42,6 +42,8 @@ this. ## Avoid IP range conflicts +The `service-cluster-ip-range` API Server flag is currently set to 10.96.0.0/16 and cannot be changed. + Swarm uses a default address pool of `10.0.0.0/16` for its overlay networks. If this conflicts with your current network implementation, please use a custom IP address pool. To specify a custom IP address pool, use the `--default-address-pool` command line option during [Swarm initialization](../../../../engine/swarm/swarm-mode.md). > **Note**: Currently, the UCP installation process does not support this flag. To deploy with a custom IP pool, Swarm must first be installed using this flag and UCP must be installed on top of it. From 054bbdb4161b0b767ca49437cae02ef225a385ae Mon Sep 17 00:00:00 2001 From: Maria Bermudez Date: Wed, 13 Feb 2019 11:33:52 -0800 Subject: [PATCH 05/23] Add DTR API Swagger spec in JSON --- reference/dtr/2.6/api/dtr-swagger-2.6.json | 9957 ++++++++++++++++++++ 1 file changed, 9957 insertions(+) create mode 100644 reference/dtr/2.6/api/dtr-swagger-2.6.json diff --git a/reference/dtr/2.6/api/dtr-swagger-2.6.json b/reference/dtr/2.6/api/dtr-swagger-2.6.json new file mode 100644 index 0000000000..0958f472c0 --- /dev/null +++ b/reference/dtr/2.6/api/dtr-swagger-2.6.json @@ -0,0 +1,9957 @@ +{ + "swagger": "2.0", + "info": { + "title": "Docker Trusted Registry", + "version": "2.6.0-tp9" + }, + "paths": { + "/api/v0/accounts/language": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "accounts" + ], + "summary": "Get the chosen language", + "operationId": "GetLanguage", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.Language" + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.Language" + } + } + } + } + }, + "/api/v0/accounts/{namespace}": { + "delete": { + "description": "\n\t*Authorization:* Client must be authenticated as a system admin.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "accounts" + ], + "summary": "Removes a user or organization along with all repositories", + "operationId": "DeleteNamespace", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + } + ], + "responses": { + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_ACCOUNT: An account with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/accounts/{namespace}/repositories": { + "delete": { + "description": "\n\t*Authorization:* Client must be authenticated as a system admin, organization admin or user in question\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "accounts" + ], + "summary": "Removes all of a user or organization's repositories", + "operationId": "DeleteNamespaceRepositories", + "deprecated": true, + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + } + ], + "responses": { + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_ACCOUNT: An account with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/accounts/{namespace}/webhooks": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"admin\" level access to the repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "accounts" + ], + "summary": "List the webhook subscriptions for a namespace", + "operationId": "ListNamespaceWebhooks", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.Webhook" + } + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_ACCOUNT: An account with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.Webhook" + } + } + } + } + } + }, + "/api/v0/accounts/{orgname}/teams/{teamname}/repositoryAccess": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as a user who owns the organization the team is in or be a member of that team.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "accounts" + ], + "summary": "List repository access grants for a team", + "operationId": "ListTeamRepoAccess", + "parameters": [ + { + "type": "string", + "description": "organization account name", + "name": "orgname", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "team name", + "name": "teamname", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The ID of the first record on the page", + "name": "pageStart", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "Maximum number of results to return", + "name": "pageSize", + "in": "query" + }, + { + "type": "boolean", + "default": false, + "description": "Whether to include the resource count in the response header", + "name": "count", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.ListTeamRepoAccess" + } + }, + "400": { + "description": "the team does not belong to the organization" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_TEAM: A team with the given name does not exist in the organization." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.ListTeamRepoAccess" + } + } + } + } + }, + "/api/v0/accounts/{username}/repositoryAccess/{namespace}/{reponame}": { + "get": { + "description": "\n\t*Authorization:* Client must be authenticated either as the user in question or be a system admin.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "accounts" + ], + "summary": "Check a user's access to a repository", + "operationId": "GetUserRepoAccess", + "parameters": [ + { + "type": "string", + "description": "user account name", + "name": "username", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.RepoUserAccess" + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_REPOSITORY: A repository with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.RepoUserAccess" + } + } + } + } + }, + "/api/v0/accounts/{username}/settings": { + "get": { + "description": "\n*Authorization:* Client must be authenticated either as the user in question or be a system admin.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "accounts" + ], + "summary": "Check a user's settings", + "operationId": "GetUserSettings", + "parameters": [ + { + "type": "string", + "description": "user account name", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.UserSettings" + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_USER: A user with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.UserSettings" + } + } + } + }, + "patch": { + "description": "\n*Authorization:* Client must be authenticated either as the user in question or be a system admin.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "accounts" + ], + "summary": "Update a user's settings", + "operationId": "UpdateUserSettings", + "parameters": [ + { + "type": "string", + "description": "user account name", + "name": "username", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.UserSettings" + } + } + ], + "responses": { + "200": { + "description": "Successfully updated user settings." + }, + "400": { + "description": "INVALID_USER_SETTINGS: The submitted user settings change request contains invalid values." + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_USER: A user with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "Successfully updated user settings." + } + } + } + }, + "/api/v0/action_configs": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "action_configs" + ], + "summary": "List all action configs", + "operationId": "ListActionConfigs", + "responses": { + "200": { + "description": "Success, list of action configs returned.", + "schema": { + "$ref": "#/definitions/tmpresponses.ActionConfigs" + } + }, + "default": { + "description": "Success, list of action configs returned.", + "schema": { + "$ref": "#/definitions/tmpresponses.ActionConfigs" + } + } + } + }, + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "action_configs" + ], + "summary": "Configure actions", + "operationId": "UpdateActionConfig", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/tmpforms.ActionConfigCreate" + } + } + ], + "responses": { + "202": { + "description": "Success.", + "schema": { + "$ref": "#/definitions/tmpresponses.ActionConfig" + } + } + } + } + }, + "/api/v0/action_configs/{action}": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "action_configs" + ], + "summary": "Get info about the actionConfig with the given action", + "operationId": "GetActionConfig", + "parameters": [ + { + "type": "string", + "description": "name of action to fetch the config for", + "name": "action", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success, action config info returned.", + "schema": { + "$ref": "#/definitions/tmpresponses.ActionConfig" + } + }, + "default": { + "description": "Success, action config info returned.", + "schema": { + "$ref": "#/definitions/tmpresponses.ActionConfig" + } + } + } + }, + "delete": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "action_configs" + ], + "summary": "Delete the action config. The defaults will be used.", + "operationId": "DeleteActionConfig", + "parameters": [ + { + "type": "string", + "description": "the name of the action to delete the config for", + "name": "action", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "Success, action config has been deleted." + } + } + } + }, + "/api/v0/api_tokens": { + "get": { + "description": "listUserAPITokensHandler", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "API_tokens" + ], + "summary": "Get all API tokens associated with user. Get all tokens if no user is not specified", + "operationId": "GetAllAPITokensByUser", + "parameters": [ + { + "type": "string", + "description": "The ID of the first record on the page", + "name": "pageStart", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "Maximum number of results to return", + "name": "pageSize", + "in": "query" + }, + { + "type": "boolean", + "default": false, + "description": "Whether to include the resource count in the response header", + "name": "count", + "in": "query" + }, + { + "type": "string", + "description": "Limit the API token results to a specific user", + "name": "username", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successfully retrieved API tokens", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.APIToken" + } + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_USER: A user with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "Successfully retrieved API tokens", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.APIToken" + } + } + } + } + }, + "post": { + "description": "createAPITokenHandler", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "API_tokens" + ], + "summary": "Create a new API token", + "operationId": "CreateAnAPIToken", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.CreateAPIToken" + } + }, + { + "type": "string", + "description": "Limit the API token results to a specific user", + "name": "username", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successfully created API token", + "schema": { + "$ref": "#/definitions/responses.NewAPIToken" + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "Successfully created API token", + "schema": { + "$ref": "#/definitions/responses.NewAPIToken" + } + } + } + }, + "delete": { + "description": "cleanupAPITokenHleanupHandler", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "API_tokens" + ], + "summary": "Mass deletion of API tokens from database based on user, time created, and/or generation method", + "operationId": "APITokenCleanup", + "parameters": [ + { + "type": "string", + "description": "Limit the API token results to a specific user", + "name": "username", + "in": "query" + }, + { + "type": "string", + "description": "The date on which the token was last used", + "name": "usedbefore", + "in": "query" + }, + { + "type": "string", + "default": "auto", + "description": "The method by which the token was created", + "name": "generatedby", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successfully cleaned up API tokens" + }, + "400": { + "description": "INVALID_PARAMETERS: Unable to parse query parameters" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_USER: A user with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "Successfully cleaned up API tokens" + } + } + } + }, + "/api/v0/api_tokens/{hashedtoken}": { + "get": { + "description": "getAPITokenHandler", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "API_tokens" + ], + "summary": "Get an API token's information based on it's token id", + "operationId": "GetAnAPIToken", + "parameters": [ + { + "type": "string", + "description": "API token id", + "name": "hashedtoken", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Successfully retrieved API token", + "schema": { + "$ref": "#/definitions/responses.APIToken" + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_API_TOKEN: An API token with the id name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "Successfully retrieved API token", + "schema": { + "$ref": "#/definitions/responses.APIToken" + } + } + } + }, + "delete": { + "description": "deleteAPITokenHandler", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "API_tokens" + ], + "summary": "Delete a specific API token", + "operationId": "DeleteAnAPIToken", + "parameters": [ + { + "type": "string", + "description": "API token id", + "name": "hashedtoken", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Successfully deleted API token" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_API_TOKEN: An API token with the id name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "Successfully deleted API token" + } + } + }, + "patch": { + "description": "updateAPITokenHandler", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "API_tokens" + ], + "summary": "Update information about a specific API token", + "operationId": "UpdateAnAPIToken", + "parameters": [ + { + "type": "string", + "description": "API token id", + "name": "hashedtoken", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.UpdateAPIToken" + } + } + ], + "responses": { + "200": { + "description": "Successfully updated API tokens", + "schema": { + "$ref": "#/definitions/responses.APIToken" + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_API_TOKEN: An API token with the id name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "Successfully updated API tokens", + "schema": { + "$ref": "#/definitions/responses.APIToken" + } + } + } + } + }, + "/api/v0/content_caches": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as any active user in the system.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "content_caches" + ], + "summary": "List all content caches", + "operationId": "ListContentCaches", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.ContentCache" + } + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.ContentCache" + } + } + } + } + }, + "post": { + "description": "\n*Authorization:* Client must be authenticated an admin.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "content_caches" + ], + "summary": "Create content cache", + "operationId": "CreateContentCache", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.CreateContentCache" + } + } + ], + "responses": { + "201": { + "description": "success", + "schema": { + "$ref": "#/definitions/responses.ContentCache" + } + }, + "400": { + "description": "invalid content cache details" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/content_caches/{contentcacheuuid}": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as any active user in the system.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "content_caches" + ], + "summary": "View details of a content cache", + "operationId": "GetContentCache", + "parameters": [ + { + "type": "string", + "description": "uuid of content cache", + "name": "contentcacheuuid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.ContentCache" + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_CONTENT_CACHE: A content cache with the given uuid does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.ContentCache" + } + } + } + }, + "delete": { + "description": "\n*Authorization:* Client must be authenticated an admin.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "content_caches" + ], + "summary": "Remove a content cache", + "operationId": "DeleteContentCache", + "parameters": [ + { + "type": "string", + "description": "uuid of content cache", + "name": "contentcacheuuid", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "success or content cache does not exist" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_CONTENT_CACHE: A content cache with the given uuid does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/crons": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "crons" + ], + "summary": "List all crons", + "operationId": "ListCrons", + "responses": { + "200": { + "description": "Success, list of crons returned.", + "schema": { + "$ref": "#/definitions/tmpresponses.Crons" + } + }, + "default": { + "description": "Success, list of crons returned.", + "schema": { + "$ref": "#/definitions/tmpresponses.Crons" + } + } + } + }, + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "crons" + ], + "summary": "Create / update a periodic task", + "operationId": "UpdateCron", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/tmpforms.CronCreate" + } + } + ], + "responses": { + "202": { + "description": "Success.", + "schema": { + "$ref": "#/definitions/tmpresponses.Cron" + } + } + } + } + }, + "/api/v0/crons/{action}": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "crons" + ], + "summary": "Get info about the cron with the given action", + "operationId": "GetCron", + "parameters": [ + { + "type": "string", + "description": "action of the cron to fetch", + "name": "action", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success, cron info returned.", + "schema": { + "$ref": "#/definitions/tmpresponses.Cron" + } + }, + "default": { + "description": "Success, cron info returned.", + "schema": { + "$ref": "#/definitions/tmpresponses.Cron" + } + } + } + }, + "delete": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "crons" + ], + "summary": "Delete the cron. Jobs created from it will not be canceled.", + "operationId": "DeleteCron", + "parameters": [ + { + "type": "string", + "description": "action of cron to delete", + "name": "action", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "Success, cron has been deleted." + } + } + } + }, + "/api/v0/events": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "events" + ], + "summary": "Get Events", + "operationId": "GetEvents", + "parameters": [ + { + "type": "string", + "description": "The ID of the first record on the page", + "name": "pageStart", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "Maximum number of results to return", + "name": "pageSize", + "in": "query" + }, + { + "type": "boolean", + "default": false, + "description": "Whether to include the resource count in the response header", + "name": "count", + "in": "query" + }, + { + "type": "string", + "name": "publishedBefore", + "in": "query" + }, + { + "type": "string", + "name": "publishedAfter", + "in": "query" + }, + { + "type": "string", + "description": "UUID of the user or organization that performed the event", + "name": "actorId", + "in": "query" + }, + { + "type": "string", + "description": "Type of events to filter by", + "name": "eventType", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.Events" + } + }, + "400": { + "description": "INVALID_PARAMETERS: Unable to parse query parameters" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.Events" + } + } + } + } + }, + "/api/v0/imagescan/layeroverride": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "imagescan" + ], + "summary": "Gets a list of all the available overrides", + "operationId": "GetLayerVulnOverrides", + "responses": { + "200": { + "description": "Successfully set vulnerability override", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.LayerVulnOverride" + } + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "500": { + "description": "INTERNAL_ERROR: An internal server error occurred. Contact a system administrator for more information." + }, + "default": { + "description": "Successfully set vulnerability override", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.LayerVulnOverride" + } + } + } + } + } + }, + "/api/v0/imagescan/layeroverride/{layerid}": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "imagescan" + ], + "summary": "Sets a vulnerability override for the given layer", + "operationId": "SetLayerVulnOverride", + "parameters": [ + { + "type": "string", + "description": "layer id", + "name": "layerid", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.VulnOverrideOption" + } + } + ], + "responses": { + "200": { + "description": "Successfully set vulnerability override" + }, + "400": { + "description": "INVALID_SETTINGS: The submitted settings change request contains invalid values." + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "404": { + "description": "NO_SUCH_LAYER: A layer with the given sha does not exist in the repository." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "500": { + "description": "INTERNAL_ERROR: An internal server error occurred. Contact a system administrator for more information." + }, + "default": { + "description": "Successfully set vulnerability override" + } + } + } + }, + "/api/v0/imagescan/layeroverride/{vulnerabilityid}": { + "delete": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "imagescan" + ], + "summary": "Deletes a layer vulnerability override", + "operationId": "DeleteLayerVulnOverride", + "parameters": [ + { + "type": "string", + "description": "vulnerability id", + "name": "vulnerabilityid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "404": { + "description": "NO_SUCH_LAYER: A layer with the given sha does not exist in the repository." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK" + } + } + } + }, + "/api/v0/imagescan/repositories/{namespace}/{reponame}/{tag}": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "imagescan" + ], + "summary": "Deprecated use /scansummary/repositories/{namespace}/{reponame}/{tag}", + "operationId": "GetSummaryByManifestDigest", + "deprecated": true, + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "tag name", + "name": "tag", + "in": "path", + "required": true + }, + { + "type": "boolean", + "default": true, + "description": "Whether to include detailed summary results", + "name": "detailed", + "in": "query" + }, + { + "type": "string", + "description": "Operating system of the tag", + "name": "os", + "in": "query" + }, + { + "type": "string", + "description": "Architecture of the tag", + "name": "arch", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successfully retrieved summary.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.OldScanSummary" + } + } + }, + "400": { + "description": "SCANNING_NOT_ENABLED: Scanning is not enabled" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "404": { + "description": "NO_SUCH_TAG: A tag with the given name does not exist for the given repository." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "Successfully retrieved summary.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.OldScanSummary" + } + } + } + } + } + }, + "/api/v0/imagescan/scan": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "imagescan" + ], + "summary": "Do a scan or a scan/check of all layers", + "operationId": "ScanAllLayers", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.ScanOptions" + } + } + ], + "responses": { + "200": { + "description": "Successfully submitted all layers to jobrunner for scan/check." + }, + "400": { + "description": "SCANNING_NOT_ENABLED: Scanning is not enabled" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "Successfully submitted all layers to jobrunner for scan/check." + } + } + } + }, + "/api/v0/imagescan/scan/update": { + "put": { + "consumes": [ + "multipart/form-data", + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "imagescan" + ], + "summary": "Update the vulnerability database for security scanning", + "operationId": "UpdateVulnDB", + "parameters": [ + { + "type": "file", + "description": "Upload file to init database", + "name": "file", + "in": "formData" + }, + { + "type": "boolean", + "default": false, + "description": "Init or update vuln db in online mode.", + "name": "online", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successfully started to updated vulnerability DB." + }, + "400": { + "description": "SCANNING_DB_NOT_READY: Scanning DB is not ready" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "Successfully started to updated vulnerability DB." + } + } + } + }, + "/api/v0/imagescan/scan/{namespace}/{reponame}/{tag}/{os}/{arch}": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "imagescan" + ], + "summary": "Do a scan or a scan/check of given image", + "operationId": "ScanImage", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "tag name", + "name": "tag", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "operating system of the tag", + "name": "os", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "architecture of the tag", + "name": "arch", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Successfully submitted image to jobrunner for scan/check." + }, + "400": { + "description": "SCANNING_NOT_ENABLED: Scanning is not enabled" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "404": { + "description": "NO_SUCH_TAG: A tag with the given name does not exist for the given repository." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "Successfully submitted image to jobrunner for scan/check." + } + } + } + }, + "/api/v0/imagescan/scansummary/component/{component}": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "imagescan" + ], + "summary": "Get the image by component", + "operationId": "GetScannedImageByComponent", + "parameters": [ + { + "type": "string", + "description": "component", + "name": "component", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The ID of the first record on the page", + "name": "pageStart", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "Maximum number of results to return", + "name": "pageSize", + "in": "query" + }, + { + "type": "boolean", + "default": false, + "description": "Whether to include the resource count in the response header", + "name": "count", + "in": "query" + }, + { + "type": "boolean", + "default": true, + "description": "Whether to include scan status summary results", + "name": "scanstatus", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successfully retrieved images", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.ScanSummary" + } + } + }, + "400": { + "description": "SCANNING_NOT_ENABLED: Scanning is not enabled" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "404": { + "description": "NO_SUCH_TAG: A tag with the given name does not exist for the given repository." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "Successfully retrieved images", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.ScanSummary" + } + } + } + } + } + }, + "/api/v0/imagescan/scansummary/cve/{cve}": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "imagescan" + ], + "summary": "Get the image by CVE", + "operationId": "GetScannedImageByCVE", + "parameters": [ + { + "type": "string", + "description": "cve", + "name": "cve", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The ID of the first record on the page", + "name": "pageStart", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "Maximum number of results to return", + "name": "pageSize", + "in": "query" + }, + { + "type": "boolean", + "default": false, + "description": "Whether to include the resource count in the response header", + "name": "count", + "in": "query" + }, + { + "type": "boolean", + "default": true, + "description": "Whether to include scan status summary results", + "name": "scanstatus", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successfully retrieved images", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.ScanSummary" + } + } + }, + "400": { + "description": "SCANNING_NOT_ENABLED: Scanning is not enabled" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "404": { + "description": "NO_SUCH_TAG: A tag with the given name does not exist for the given repository." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "Successfully retrieved images", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.ScanSummary" + } + } + } + } + } + }, + "/api/v0/imagescan/scansummary/layer/{layerid}": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "imagescan" + ], + "summary": "Get the image by layer sha", + "operationId": "GetScannedImageByLayer", + "parameters": [ + { + "type": "string", + "description": "layer id", + "name": "layerid", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The ID of the first record on the page", + "name": "pageStart", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "Maximum number of results to return", + "name": "pageSize", + "in": "query" + }, + { + "type": "boolean", + "default": false, + "description": "Whether to include the resource count in the response header", + "name": "count", + "in": "query" + }, + { + "type": "boolean", + "default": true, + "description": "Whether to include scan status summary results", + "name": "scanstatus", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successfully retrieved images", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.ScanSummary" + } + } + }, + "400": { + "description": "SCANNING_NOT_ENABLED: Scanning is not enabled" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "404": { + "description": "NO_SUCH_LAYER: A layer with the given sha does not exist in the repository." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "Successfully retrieved images", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.ScanSummary" + } + } + } + } + } + }, + "/api/v0/imagescan/scansummary/license/{license}": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "imagescan" + ], + "summary": "Get the image by license", + "operationId": "GetScannedImageByLicense", + "parameters": [ + { + "type": "string", + "description": "license", + "name": "license", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The ID of the first record on the page", + "name": "pageStart", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "Maximum number of results to return", + "name": "pageSize", + "in": "query" + }, + { + "type": "boolean", + "default": false, + "description": "Whether to include the resource count in the response header", + "name": "count", + "in": "query" + }, + { + "type": "boolean", + "default": true, + "description": "Whether to include scan status summary results", + "name": "scanstatus", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successfully retrieved images", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.ScanSummary" + } + } + }, + "400": { + "description": "SCANNING_NOT_ENABLED: Scanning is not enabled" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "404": { + "description": "NO_SUCH_TAG: A tag with the given name does not exist for the given repository." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "Successfully retrieved images", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.ScanSummary" + } + } + } + } + } + }, + "/api/v0/imagescan/scansummary/repositories/{namespace}/{reponame}/{reference}": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "imagescan" + ], + "summary": "Get the scan summary info on a namespace/repo:tag or namespace/repo@digest", + "operationId": "GetScanSummary", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "digest or tag for an image manifest", + "name": "reference", + "in": "path", + "required": true + }, + { + "type": "boolean", + "default": true, + "description": "Whether to include scan status summary results", + "name": "scanstatus", + "in": "query" + }, + { + "type": "string", + "description": "Operating system of the tag", + "name": "os", + "in": "query" + }, + { + "type": "string", + "description": "Architecture of the tag", + "name": "arch", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successfully retrieved summary.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.ScanSummary" + } + } + }, + "400": { + "description": "SCANNING_NOT_ENABLED: Scanning is not enabled" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "404": { + "description": "NO_SUCH_REF: A ref with the given name does not exist for the given repository." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "Successfully retrieved summary.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.ScanSummary" + } + } + } + } + } + }, + "/api/v0/imagescan/scansummary/repositories/{namespace}/{reponame}/{tag}/export": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "text/csv", + "application/json" + ], + "tags": [ + "imagescan" + ], + "summary": "Get the scan summary info on a namespace/repo:tag as a file", + "operationId": "ExportScanSummary", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "tag name", + "name": "tag", + "in": "path", + "required": true + }, + { + "type": "boolean", + "default": true, + "description": "Whether to include scan status summary results", + "name": "scanstatus", + "in": "query" + }, + { + "type": "string", + "description": "Operating system of the tag", + "name": "os", + "in": "query" + }, + { + "type": "string", + "description": "Architecture of the tag", + "name": "arch", + "in": "query" + }, + { + "type": "string", + "description": "Scan summary exported filetype", + "name": "Accept", + "in": "header" + } + ], + "responses": { + "400": { + "description": "INVALID_PARAMETERS: Unable to parse query parameters" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "404": { + "description": "NO_SUCH_TAG: A tag with the given name does not exist for the given repository." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/imagescan/scansummary/tags": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "imagescan" + ], + "summary": "Get a list of scan summaries", + "operationId": "GetScanSummaries", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.ImagesForm" + } + } + ], + "responses": { + "200": { + "description": "Successfully retrieved summary.", + "schema": { + "$ref": "#/definitions/responses.ThinScanSummaries" + } + }, + "400": { + "description": "INVALID_PARAMETERS: Unable to parse query parameters" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "Successfully retrieved summary.", + "schema": { + "$ref": "#/definitions/responses.ThinScanSummaries" + } + } + } + } + }, + "/api/v0/imagescan/status": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "imagescan" + ], + "summary": "Get the status and version of scanning service", + "operationId": "GetNautilusDBStatus", + "responses": { + "200": { + "description": "Successfully retrieved DB status", + "schema": { + "$ref": "#/definitions/responses.NautilusStatus" + } + }, + "400": { + "description": "SCANNING_NOT_ENABLED: Scanning is not enabled" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "Successfully retrieved DB status", + "schema": { + "$ref": "#/definitions/responses.NautilusStatus" + } + } + } + } + }, + "/api/v0/index/autocomplete": { + "get": { + "description": "\nRepository results will be filtered to only those repositories visible to the client. Account results will not be filtered.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "index" + ], + "summary": "Autocompletion for repositories and/or accounts", + "operationId": "Autocomplete", + "parameters": [ + { + "type": "string", + "description": "Autocomplete query", + "name": "query", + "in": "query", + "required": true + }, + { + "type": "boolean", + "default": true, + "description": "Whether to include repositories in the response", + "name": "includeRepositories", + "in": "query" + }, + { + "type": "boolean", + "default": true, + "description": "Whether to include accounts in the response", + "name": "includeAccounts", + "in": "query" + }, + { + "type": "string", + "description": "Exact repository namespace to limit results to.", + "name": "namespace", + "in": "query" + }, + { + "type": "number", + "default": 25, + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.Autocomplete" + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.Autocomplete" + } + } + } + } + }, + "/api/v0/index/dockersearch": { + "get": { + "description": "\nThis is used for the Docker CLI's docker search command. Repository results will be filtered to only those repositories visible to the client.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "index" + ], + "summary": "Search Docker repositories", + "operationId": "Docker Search", + "parameters": [ + { + "type": "string", + "description": "Search query", + "name": "q", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.DockerSearch" + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.DockerSearch" + } + } + } + } + }, + "/api/v0/jobs": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "jobs" + ], + "summary": "List all jobs ordered by most recently scheduled", + "operationId": "ListJobs", + "parameters": [ + { + "type": "string", + "default": "any", + "description": "Filter jobs by action.", + "name": "action", + "in": "query" + }, + { + "type": "string", + "default": "any", + "description": "Filter jobs by worker ID.", + "name": "worker", + "in": "query" + }, + { + "type": "string", + "default": "any", + "description": "Show only jobs that are running.", + "name": "running", + "in": "query" + }, + { + "type": "integer", + "default": 0, + "description": "Return most recently scheduled jobs starting from this offset index.", + "name": "start", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "Maximum number of jobs per page of results.", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Success, list of jobs returned.", + "schema": { + "$ref": "#/definitions/tmpresponses.Jobs" + } + }, + "default": { + "description": "Success, list of jobs returned.", + "schema": { + "$ref": "#/definitions/tmpresponses.Jobs" + } + } + } + }, + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "jobs" + ], + "summary": "Schedule a job to be run immediately", + "operationId": "CreateJob", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/tmpforms.JobSubmission" + } + } + ], + "responses": { + "202": { + "description": "Success, job waiting to be claimed.", + "schema": { + "$ref": "#/definitions/tmpresponses.Job" + } + } + } + } + }, + "/api/v0/jobs/{jobID}": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "jobs" + ], + "summary": "Get info about the job with the given ID", + "operationId": "GetJob", + "parameters": [ + { + "type": "string", + "description": "ID of job to fetch", + "name": "jobID", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Success, job info returned.", + "schema": { + "$ref": "#/definitions/tmpresponses.Job" + } + }, + "default": { + "description": "Success, job info returned.", + "schema": { + "$ref": "#/definitions/tmpresponses.Job" + } + } + } + }, + "delete": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "jobs" + ], + "summary": "Signal this job's worker to cancel and delete the job", + "operationId": "DeleteJobs", + "parameters": [ + { + "type": "string", + "description": "ID of job to delete", + "name": "jobID", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "Success, job has been deleted." + } + } + } + }, + "/api/v0/jobs/{jobID}/cancel": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "jobs" + ], + "summary": "Signal this job's worker to cancel the job", + "operationId": "CancelJob", + "parameters": [ + { + "type": "string", + "description": "ID of job to cancel", + "name": "jobID", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "Success, job has been canceled." + } + } + } + }, + "/api/v0/jobs/{jobID}/logs": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "jobs" + ], + "summary": "Retrieve logs for this job from its worker", + "operationId": "GetJobLogs", + "parameters": [ + { + "type": "string", + "description": "ID of job whose logs to retrieve", + "name": "jobID", + "in": "path", + "required": true + }, + { + "type": "boolean", + "default": false, + "description": "t/f: stream new logs", + "name": "stream", + "in": "query" + }, + { + "type": "integer", + "default": 0, + "description": "Line number to start from", + "name": "offset", + "in": "query" + }, + { + "type": "integer", + "default": 0, + "description": "Number of lines to return if not streaming", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Success, job's logs returned.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/tmpresponses.JobLog" + } + } + }, + "default": { + "description": "Success, job's logs returned.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/tmpresponses.JobLog" + } + } + } + } + } + }, + "/api/v0/meta/alerts": { + "get": { + "description": "\n*Authorization:* Client must be authenticated an admin.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "meta" + ], + "summary": "Get alerts", + "operationId": "GetAlerts", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.Alert" + } + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.Alert" + } + } + } + } + } + }, + "/api/v0/meta/cluster_status": { + "get": { + "description": "\n*Authorization:* Client must be authenticated an admin.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "meta" + ], + "summary": "Get cluster status", + "operationId": "GetClusterStatus", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.ClusterStatus" + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.ClusterStatus" + } + } + } + } + }, + "/api/v0/meta/features": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as any active user in the system\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "meta" + ], + "summary": "Get features", + "operationId": "GetFeatures", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.Features" + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.Features" + } + } + } + } + }, + "/api/v0/meta/settings": { + "get": { + "description": "\n*Authorization:* Client must be authenticated an admin.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "meta" + ], + "summary": "Get settings", + "operationId": "GetSettings", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.Settings" + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.Settings" + } + } + } + }, + "post": { + "description": "\n*Authorization:* Client must be authenticated an admin.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "meta" + ], + "summary": "Update settings", + "operationId": "UpdateSettings", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.Settings" + } + } + ], + "responses": { + "202": { + "description": "success" + }, + "400": { + "description": "INVALID_SETTINGS: The submitted settings change request contains invalid values." + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/remote/registry": { + "post": { + "description": "\n*Authorization:* Client must be authenticated as any active user in the system. Credentials provided in the request body must be for an active user in the remote system.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "remote" + ], + "summary": "Create a check for connection status of remote registry", + "operationId": "CreateRemoteRegistryCheck", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.CreateRemoteRegistryCheck" + } + } + ], + "responses": { + "201": { + "description": "success", + "schema": { + "$ref": "#/definitions/responses.RemoteRegistryCheck" + } + }, + "400": { + "description": "REMOTE_REGISTRY_INVALID_PERMISSIONS: Remote user not authorized to access the requested resource." + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/repositories": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as any active user in the system. Results will be filtered to only those repositories visible to the client.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "List all repositories", + "operationId": "ListRepositories", + "parameters": [ + { + "type": "string", + "description": "The ID of the first record on the page", + "name": "pageStart", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "Maximum number of results to return", + "name": "pageSize", + "in": "query" + }, + { + "type": "boolean", + "default": false, + "description": "Whether to include the resource count in the response header", + "name": "count", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.Repositories" + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.Repositories" + } + } + } + } + }, + "/api/v0/repositories/scan/toggle": { + "post": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"admin\" access to the repository\n(i.e., user owns the repo or is a member of a team with \"admin\" level access to the organization\"s repository).\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Toggles scan on push for all repositories", + "operationId": "ToggleAllRepositoriesScanOnPush", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.ToggleScanOnPush" + } + } + ], + "responses": { + "200": { + "description": "Successfully toggled scan on push for all repositories." + }, + "400": { + "description": "INVALID_JSON: Unable to parse JSON" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "Successfully toggled scan on push for all repositories." + } + } + } + }, + "/api/v0/repositories/{namespace}": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as any active user in the system. Results will be filtered to only those repositories visible to the client.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "List repositories in a namespace", + "operationId": "ListNamespaceRepositories", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The ID of the first record on the page", + "name": "pageStart", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "Maximum number of results to return", + "name": "pageSize", + "in": "query" + }, + { + "type": "boolean", + "default": false, + "description": "Whether to include the resource count in the response header", + "name": "count", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.Repositories" + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "404": { + "description": "NO_SUCH_ACCOUNT: An account with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.Repositories" + } + } + } + }, + "post": { + "description": "\n*Authorization:* Client must be authenticated as a user who has admin access to the\nrepository namespace (i.e., user owns the repo or is a member of a team with\n\"admin\" level access to the organization's namespace of repositories).\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Create repository", + "operationId": "CreateRepository", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.CreateRepo" + } + } + ], + "responses": { + "201": { + "description": "success", + "schema": { + "$ref": "#/definitions/responses.Repository" + } + }, + "400": { + "description": "REPOSITORY_EXISTS: A repository with the same name already exists." + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_ACCOUNT: An account with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as a user who has visibility to the repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "View details of a repository", + "operationId": "GetRepository", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.Repository" + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "404": { + "description": "NO_SUCH_REPOSITORY: A repository with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.Repository" + } + } + } + }, + "delete": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"admin\" access to the repository\n(i.e., user owns the repo or is a member of a team with \"admin\" level access to the organization\"s repository).\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Remove a repository", + "operationId": "DeleteRepository", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The domain used to push tags to DTR. Must be set to obtain/manipulate Notary related information", + "name": "domain", + "in": "query" + } + ], + "responses": { + "204": { + "description": "success or repository does not exist" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_REPOSITORY: A repository with the given name does not exist." + }, + "405": { + "description": "REPOSITORY_CONTAINS_TAGS_IN_NOTARY: This repository contains tags in notary and can't be deleted until all tags in notary are removed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + }, + "patch": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"admin\" access to the repository\n(i.e., user owns the repo or is a member of a team with \"admin\" level access to the organization\"s repository).\n\nNote that a repository cannot be renamed this way.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Update details of a repository", + "operationId": "PatchRepository", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.UpdateRepo" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.Repository" + } + }, + "400": { + "description": "INVALID_REPOSITORY_VISIBILITY: The visibility value of the repository is invalid." + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_REPOSITORY: A repository with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.Repository" + } + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}/events": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as a user who has visibility to local repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "List the events for a repository", + "operationId": "ListRepoEvents", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The ID of the first record on the page", + "name": "pageStart", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "Maximum number of results to return", + "name": "pageSize", + "in": "query" + }, + { + "type": "boolean", + "default": false, + "description": "Whether to include the resource count in the response header", + "name": "count", + "in": "query" + }, + { + "type": "string", + "name": "publishedBefore", + "in": "query" + }, + { + "type": "string", + "name": "publishedAfter", + "in": "query" + }, + { + "type": "string", + "description": "UUID of the user or organization that performed the event", + "name": "actorId", + "in": "query" + }, + { + "type": "string", + "description": "Type of events to filter by", + "name": "eventType", + "in": "query" + }, + { + "type": "boolean", + "default": false, + "description": "Exclude image pull events", + "name": "excludePull", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.Events" + } + }, + "400": { + "description": "INVALID_PARAMETERS: Unable to parse query parameters" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_REPOSITORY: A repository with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.Events" + } + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}/manifests": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as a user who has visibility to the repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "List the available manifests for a repository", + "operationId": "ListRepoManifests", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The ID of the first record on the page", + "name": "pageStart", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "Maximum number of results to return", + "name": "pageSize", + "in": "query" + }, + { + "type": "boolean", + "default": false, + "description": "Whether to include the resource count in the response header", + "name": "count", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.Manifest" + } + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "404": { + "description": "NO_SUCH_REPOSITORY: A repository with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.Manifest" + } + } + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}/manifests/{reference}": { + "delete": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"write\" level access to the repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Delete a manifest for a repository", + "operationId": "DeleteRepoManifest", + "deprecated": true, + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "digest or tag for an image manifest", + "name": "reference", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "success" + }, + "400": { + "description": "INVALID_DIGEST: The given digest is invalid." + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_REF: A ref with the given name does not exist for the given repository." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}/mirroringPolicies": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as a user who has visibility to local repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "List the mirroring policies for a repository", + "operationId": "ListRepoMirroringPolicies", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The ID of the first record on the page", + "name": "pageStart", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "Maximum number of results to return", + "name": "pageSize", + "in": "query" + }, + { + "type": "boolean", + "default": false, + "description": "Whether to include the resource count in the response header", + "name": "count", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.MirroringPolicy" + } + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_REPOSITORY: A repository with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.MirroringPolicy" + } + } + } + } + }, + "delete": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"admin\" level access to the local repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Deletes a set of mirroring policies for a repository", + "operationId": "DeleteRepoMirroringPolicies", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/forms.DeleteMirroringPolicyIDs" + } + } + } + ], + "responses": { + "204": { + "description": "success" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_REPOSITORY: A repository with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}/pollMirroringPolicies": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as a user who has visibility to local repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "List the poll mirroring policies for a repository", + "operationId": "ListRepoPollMirroringPolicies", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.PollMirroringPolicy" + } + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_REPOSITORY: A repository with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.PollMirroringPolicy" + } + } + } + } + }, + "post": { + "description": "*Authorization:* Client must be authenticated as a user who has \"admin\" level access to the local repository and credentials to the remote repository.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Create a poll mirroring policy for a repository", + "operationId": "CreateRepoPollMirroringPolicy", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "boolean", + "default": true, + "description": "Whether to evaluate the policy on creation", + "name": "initialEvaluation", + "in": "query" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.CreatePollMirroringPolicy" + } + } + ], + "responses": { + "201": { + "description": "success", + "schema": { + "$ref": "#/definitions/responses.PollMirroringPolicy" + } + }, + "400": { + "description": "REMOTE_REGISTRY_INVALID_PERMISSIONS: Remote user not authorized to access the requested resource." + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "INVALID_POLL_MIRRORING_POLICY: The given poll mirroring policy is invalid." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}/pollMirroringPolicies/{pollmirroringpolicyid}": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as a user who has visibility to the local repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Retrieve a specific poll mirroring policy for a repository", + "operationId": "GetRepoPollMirroringPolicy", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "poll mirroring policy id", + "name": "pollmirroringpolicyid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.PollMirroringPolicy" + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_POLL_MIRRORING_POLICY: A poll mirroring policy with the given id does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.PollMirroringPolicy" + } + } + } + }, + "put": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"admin\" level access to the local repository and credentials to the remote repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Updates a specific poll mirroring policy for a repository", + "operationId": "UpdateRepoPollMirroringPolicy", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "poll mirroring policy id", + "name": "pollmirroringpolicyid", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.UpdatePollMirroringPolicy" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.PollMirroringPolicy" + } + }, + "400": { + "description": "REMOTE_REGISTRY_INVALID_PERMISSIONS: Remote user not authorized to access the requested resource." + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "INVALID_POLL_MIRRORING_POLICY: The given poll mirroring policy is invalid." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.PollMirroringPolicy" + } + } + } + }, + "delete": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"admin\" level access to the local repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Deletes a specific poll mirroring policy for a repository", + "operationId": "DeleteRepoPollMirroringPolicy", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "poll mirroring policy id", + "name": "pollmirroringpolicyid", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "success or poll mirroring policy does not exist" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_POLL_MIRRORING_POLICY: A poll mirroring policy with the given id does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}/promotionPolicies": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as a user who has visibility to the source or target repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "List the promotion policies for a repository", + "operationId": "ListRepoPromotionPolicies", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "boolean", + "default": true, + "description": "Whether to list promotion policies for a repository as a source or destination.", + "name": "source", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.PromotionPolicy" + } + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_REPOSITORY: A repository with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.PromotionPolicy" + } + } + } + } + }, + "post": { + "description": "*Authorization:* Client must be authenticated as a user who has \"admin\" level access to the source and target repository.\nRules for the policy can be on the following fields and their respective operators:\n- \"tag\"\n\t- \"eq\": equals\n\t- \"sw\": starts with\n\t- \"ew\": ends with\n\t- \"c\": contains\n\t- \"oo\": one of\n\t- \"noo\": not one of\n- \"license.name\"\n\t- \"oo\": one of\n\t- \"noo\": not one of\n- \"component.name\"\n\t- \"oo\": one of\n\t- \"noo\": not one of\n- \"vulnerability_all\"\n\t- \"gte\": greater than or equals\n\t- \"gt\": greater than\n\t- \"eq\": equals\n\t- \"neq\": not equals\n\t- \"lte\": less than or equals\n\t- \"lt\": less than\n- \"vulnerability_critical\"\n\t- \"gte\": greater than or equals\n\t- \"gt\": greater than\n\t- \"eq\": equals\n\t- \"neq\": not equals\n\t- \"lte\": less than or equals\n\t- \"lt\": less than\n- \"vulnerability_major\"\n\t- \"gte\": greater than or equals\n\t- \"gt\": greater than\n\t- \"eq\": equals\n\t- \"neq\": not equals\n\t- \"lte\": less than or equals\n\t- \"lt\": less than\n- \"vulnerability_minor\"\n\t- \"gte\": greater than or equals\n\t- \"gt\": greater than\n\t- \"eq\": equals\n\t- \"neq\": not equals\n\t- \"lte\": less than or equals\n\t- \"lt\": less than\n- \"updated_at\"\n\t- \"bf\": before\n\t- \"af\": after\n- \"updated_at_duration\"\n\t- \"bf\": before\n\t- \"af\": after\n\nThe tag template is used to rename the tag in the target repository. The\nfollowing symbols are allowed:\n- \"%n\": The tag to promote (e.g. 1, 4.5, latest)\n- \"%A\": Day of the week (e.g. Sunday, Monday)\n- \"%a\": Day of the week, abbreviated (e.g. Sun, Mon , Tue)\n- \"%w\": Day of the week, as a number (e.g. 0, 1, 6)\n- \"%d\": Number for the day of the month (e.g. 01, 15, 31)\n- \"%B\": Month (e.g. January, December)\n- \"%b\": Month, abbreviated (e.g. Jan, Jun, Dec)\n- \"%m\": Month, as a number (e.g. 01, 06, 12)\n- \"%Y\": Year (e.g. 1999, 2015, 2048)\n- \"%y\": Year, two digits (e.g. 99, 15, 48)\n- \"%H\": Hour, in 24 hour format (e.g. 00, 12, 23)\n- \"%I\": Hour, in 12 hour format (e.g. 01, 10, 10)\n- \"%p\": Period of the day (e.g. AM, PM)\n- \"%M\": Minute (e.g. 00, 10, 59)\n- \"%S\": Second (e.g. 00, 10, 59)\n- \"%f\": Microsecond (e.g. 000000, 999999)\n- \"%Z\": Name for the timezone (e.g. UTC, PST, EST)\n- \"%j\": Day of the year (e.g. 001, 200, 366)\n- \"%W\": Week of the year (e.g. 00, 10 , 53)\n", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Create a promotion policy for a repository", + "operationId": "CreateRepoPromotionPolicy", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "boolean", + "default": true, + "description": "Whether to evaluate the policy on creation", + "name": "initialEvaluation", + "in": "query" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.CreatePromotionPolicy" + } + } + ], + "responses": { + "201": { + "description": "success", + "schema": { + "$ref": "#/definitions/responses.PromotionPolicy" + } + }, + "400": { + "description": "INVALID_PROMOTION_POLICY: The given promotion policy is invalid." + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_REPOSITORY: A repository with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}/promotionPolicies/{promotionpolicyid}": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as a user who has visibility to the source or target repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Retrieve a specific promotion policy for a repository", + "operationId": "GetRepoPromotionPolicy", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "promotion policy id", + "name": "promotionpolicyid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.PromotionPolicy" + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_PROMOTION_POLICY: A promotion policy with the given id does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.PromotionPolicy" + } + } + } + }, + "put": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"admin\" level access to the source and target repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Updates a specific promotion policy for a repository", + "operationId": "UpdateRepoPromotionPolicy", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "promotion policy id", + "name": "promotionpolicyid", + "in": "path", + "required": true + }, + { + "type": "boolean", + "default": true, + "description": "Whether to evaluate the policy on creation", + "name": "initialEvaluation", + "in": "query" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.UpdatePromotionPolicy" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.PromotionPolicy" + } + }, + "400": { + "description": "INVALID_PROMOTION_POLICY: The given promotion policy is invalid." + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_PROMOTION_POLICY: A promotion policy with the given id does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.PromotionPolicy" + } + } + } + }, + "delete": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"admin\" level access to the source or target repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Deletes a specific promotion policy for a repository", + "operationId": "DeleteRepoPromotionPolicy", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "promotion policy id", + "name": "promotionpolicyid", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "success or promotion policy does not exist" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_PROMOTION_POLICY: A promotion policy with the given id does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}/pruningPolicies": { + "get": { + "description": "*Authorization:* Client must be authenticated as a user who has visibility to the repository.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "List the pruning policies for a repository", + "operationId": "ListRepoPruningPolicies", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The ID of the first record on the page", + "name": "pageStart", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "Maximum number of results to return", + "name": "pageSize", + "in": "query" + }, + { + "type": "boolean", + "default": false, + "description": "Whether to include the resource count in the response header", + "name": "count", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.PruningPolicy" + } + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_REPOSITORY: A repository with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.PruningPolicy" + } + } + } + } + }, + "post": { + "description": "*Authorization:* Client must be authenticated as a user who has \"admin\" level access to the repository.\nRules for the policy can be on the following fields and their respective operators:\n- \"tag\"\n\t- \"eq\": equals\n\t- \"sw\": starts with\n\t- \"ew\": ends with\n\t- \"c\": contains\n\t- \"oo\": one of\n\t- \"noo\": not one of\n- \"license.name\"\n\t- \"oo\": one of\n\t- \"noo\": not one of\n- \"component.name\"\n\t- \"oo\": one of\n\t- \"noo\": not one of\n- \"vulnerability_all\"\n\t- \"gte\": greater than or equals\n\t- \"gt\": greater than\n\t- \"eq\": equals\n\t- \"neq\": not equals\n\t- \"lte\": less than or equals\n\t- \"lt\": less than\n- \"vulnerability_critical\"\n\t- \"gte\": greater than or equals\n\t- \"gt\": greater than\n\t- \"eq\": equals\n\t- \"neq\": not equals\n\t- \"lte\": less than or equals\n\t- \"lt\": less than\n- \"vulnerability_major\"\n\t- \"gte\": greater than or equals\n\t- \"gt\": greater than\n\t- \"eq\": equals\n\t- \"neq\": not equals\n\t- \"lte\": less than or equals\n\t- \"lt\": less than\n- \"vulnerability_minor\"\n\t- \"gte\": greater than or equals\n\t- \"gt\": greater than\n\t- \"eq\": equals\n\t- \"neq\": not equals\n\t- \"lte\": less than or equals\n\t- \"lt\": less than\n- \"updated_at\"\n\t- \"bf\": before\n\t- \"af\": after\n- \"updated_at_duration\"\n\t- \"bf\": before\n\t- \"af\": after\n", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Create a pruning policy for a repository", + "operationId": "CreateRepoPruningPolicy", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "boolean", + "default": true, + "description": "Whether to evaluate the policy on creation", + "name": "initialEvaluation", + "in": "query" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.CreatePruningPolicy" + } + } + ], + "responses": { + "201": { + "description": "success", + "schema": { + "$ref": "#/definitions/responses.PruningPolicy" + } + }, + "400": { + "description": "REMOTE_REGISTRY_INVALID_PERMISSIONS: Remote user not authorized to access the requested resource." + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "INVALID_PRUNING_POLICY: The given pruning policy is invalid." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}/pruningPolicies/test": { + "post": { + "description": "*Authorization:* Client must be authenticated as a user who has \"admin\" level access to the repository.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Test a pruning policy for a repository", + "operationId": "TestRepoPruningPolicy", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The ID of the first record on the page", + "name": "pageStart", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "Maximum number of results to return", + "name": "pageSize", + "in": "query" + }, + { + "type": "boolean", + "default": false, + "description": "Whether to include the resource count in the response header", + "name": "count", + "in": "query" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.CreatePruningPolicy" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.ThinTag" + } + } + }, + "400": { + "description": "REMOTE_REGISTRY_INVALID_PERMISSIONS: Remote user not authorized to access the requested resource." + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "INVALID_PRUNING_POLICY: The given pruning policy is invalid." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.ThinTag" + } + } + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}/pruningPolicies/{pruningpolicyid}": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as a user who has visibility to the local repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Retrieve a specific pruning policy for a repository", + "operationId": "GetRepoPruningPolicy", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "pruning policy id", + "name": "pruningpolicyid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.PruningPolicy" + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_PRUNING_POLICY: A pruning policy with the given id does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.PruningPolicy" + } + } + } + }, + "put": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"admin\" level access to the repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Updates a specific pruning policy for a repository", + "operationId": "UpdateRepoPruningPolicy", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "pruning policy id", + "name": "pruningpolicyid", + "in": "path", + "required": true + }, + { + "type": "boolean", + "default": true, + "description": "Whether to evaluate the policy on creation", + "name": "initialEvaluation", + "in": "query" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.UpdatePruningPolicy" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.PruningPolicy" + } + }, + "400": { + "description": "REMOTE_REGISTRY_INVALID_PERMISSIONS: Remote user not authorized to access the requested resource." + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "INVALID_PRUNING_POLICY: The given pruning policy is invalid." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.PruningPolicy" + } + } + } + }, + "delete": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"admin\" level access to the repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Deletes a specific pruning policy for a repository", + "operationId": "DeleteRepoPruningPolicy", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "pruning policy id", + "name": "pruningpolicyid", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "success or pruning policy does not exist" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_PRUNING_POLICY: A pruning policy with the given id does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}/pushMirroringPolicies": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as a user who has visibility to local repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "List the push mirroring policies for a repository", + "operationId": "ListRepoPushMirroringPolicies", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.PushMirroringPolicy" + } + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_REPOSITORY: A repository with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.PushMirroringPolicy" + } + } + } + } + }, + "post": { + "description": "*Authorization:* Client must be authenticated as a user who has \"admin\" level access to the local repository and credentials to the remote repository.\nRules for the policy can be on the following fields and their respective operators:\n- \"tag\"\n\t- \"eq\": equals\n\t- \"sw\": starts with\n\t- \"ew\": ends with\n\t- \"c\": contains\n\t- \"oo\": one of\n\t- \"noo\": not one of\n- \"license.name\"\n\t- \"oo\": one of\n\t- \"noo\": not one of\n- \"component.name\"\n\t- \"oo\": one of\n\t- \"noo\": not one of\n- \"vulnerability_all\"\n\t- \"gte\": greater than or equals\n\t- \"gt\": greater than\n\t- \"eq\": equals\n\t- \"neq\": not equals\n\t- \"lte\": less than or equals\n\t- \"lt\": less than\n- \"vulnerability_critical\"\n\t- \"gte\": greater than or equals\n\t- \"gt\": greater than\n\t- \"eq\": equals\n\t- \"neq\": not equals\n\t- \"lte\": less than or equals\n\t- \"lt\": less than\n- \"vulnerability_major\"\n\t- \"gte\": greater than or equals\n\t- \"gt\": greater than\n\t- \"eq\": equals\n\t- \"neq\": not equals\n\t- \"lte\": less than or equals\n\t- \"lt\": less than\n- \"vulnerability_minor\"\n\t- \"gte\": greater than or equals\n\t- \"gt\": greater than\n\t- \"eq\": equals\n\t- \"neq\": not equals\n\t- \"lte\": less than or equals\n\t- \"lt\": less than\n- \"updated_at\"\n\t- \"bf\": before\n\t- \"af\": after\n- \"updated_at_duration\"\n\t- \"bf\": before\n\t- \"af\": after\n\nThe tag template is used to rename the tag in the target repository. The\nfollowing symbols are allowed:\n- \"%n\": The tag to promote (e.g. 1, 4.5, latest)\n- \"%A\": Day of the week (e.g. Sunday, Monday)\n- \"%a\": Day of the week, abbreviated (e.g. Sun, Mon , Tue)\n- \"%w\": Day of the week, as a number (e.g. 0, 1, 6)\n- \"%d\": Number for the day of the month (e.g. 01, 15, 31)\n- \"%B\": Month (e.g. January, December)\n- \"%b\": Month, abbreviated (e.g. Jan, Jun, Dec)\n- \"%m\": Month, as a number (e.g. 01, 06, 12)\n- \"%Y\": Year (e.g. 1999, 2015, 2048)\n- \"%y\": Year, two digits (e.g. 99, 15, 48)\n- \"%H\": Hour, in 24 hour format (e.g. 00, 12, 23)\n- \"%I\": Hour, in 12 hour format (e.g. 01, 10, 10)\n- \"%p\": Period of the day (e.g. AM, PM)\n- \"%M\": Minute (e.g. 00, 10, 59)\n- \"%S\": Second (e.g. 00, 10, 59)\n- \"%f\": Microsecond (e.g. 000000, 999999)\n- \"%Z\": Name for the timezone (e.g. UTC, PST, EST)\n- \"%j\": Day of the year (e.g. 001, 200, 366)\n- \"%W\": Week of the year (e.g. 00, 10 , 53)\n", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Create a push mirroring policy for a repository", + "operationId": "CreateRepoPushMirroringPolicy", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "boolean", + "default": true, + "description": "Whether to evaluate the policy on creation", + "name": "initialEvaluation", + "in": "query" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.CreatePushMirroringPolicy" + } + } + ], + "responses": { + "201": { + "description": "success", + "schema": { + "$ref": "#/definitions/responses.PushMirroringPolicy" + } + }, + "400": { + "description": "REMOTE_REGISTRY_INVALID_PERMISSIONS: Remote user not authorized to access the requested resource." + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "INVALID_PUSH_MIRRORING_POLICY: The given push mirroring policy is invalid." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}/pushMirroringPolicies/{pushmirroringpolicyid}": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as a user who has visibility to the local repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Retrieve a specific push mirroring policy for a repository", + "operationId": "GetRepoPushMirroringPolicy", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "push mirroring policy id", + "name": "pushmirroringpolicyid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.PushMirroringPolicy" + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_PUSH_MIRRORING_POLICY: A push mirroring policy with the given id does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.PushMirroringPolicy" + } + } + } + }, + "put": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"admin\" level access to the local repository and credentials to the remote repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Updates a specific push mirroring policy for a repository", + "operationId": "UpdateRepoPushMirroringPolicy", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "push mirroring policy id", + "name": "pushmirroringpolicyid", + "in": "path", + "required": true + }, + { + "type": "boolean", + "default": true, + "description": "Whether to evaluate the policy on creation", + "name": "initialEvaluation", + "in": "query" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.UpdatePushMirroringPolicy" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.PushMirroringPolicy" + } + }, + "400": { + "description": "REMOTE_REGISTRY_INVALID_PERMISSIONS: Remote user not authorized to access the requested resource." + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "INVALID_PUSH_MIRRORING_POLICY: The given push mirroring policy is invalid." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.PushMirroringPolicy" + } + } + } + }, + "delete": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"admin\" level access to the local repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Deletes a specific push mirroring policy for a repository", + "operationId": "DeleteRepoPushMirroringPolicy", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "push mirroring policy id", + "name": "pushmirroringpolicyid", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "success or push mirroring policy does not exist" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_PUSH_MIRRORING_POLICY: A push mirroring policy with the given id does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}/tags": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as a user who has visibility to the repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "List the available tags for a repository", + "operationId": "ListRepoTags", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The ID of the first record on the page", + "name": "pageStart", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "Maximum number of results to return", + "name": "pageSize", + "in": "query" + }, + { + "type": "boolean", + "default": false, + "description": "Whether to include the resource count in the response header", + "name": "count", + "in": "query" + }, + { + "type": "boolean", + "default": false, + "description": "Whether to include the manifest for each tag", + "name": "includeManifests", + "in": "query" + }, + { + "type": "string", + "description": "The domain used to push tags to DTR. Must be set to obtain/manipulate Notary related information", + "name": "domain", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.ListTag" + } + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_REPOSITORY: A repository with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.ListTag" + } + } + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}/tags/{reference}": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as a user who has visibility to the repository.\nIf the ref given is to a manifest list, multiple Tag objects will be returned, one for each manifest in the list.\nSimilarly if the ref is a digest the API will return all tags referencing that digest.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Retrieve a specific tag for a repository", + "operationId": "ListRepoTag", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "digest or tag for an image manifest", + "name": "reference", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The domain used to push tags to DTR. Must be set to obtain/manipulate Notary related information", + "name": "domain", + "in": "query" + }, + { + "type": "string", + "description": "Operating system of the tag", + "name": "os", + "in": "query" + }, + { + "type": "string", + "description": "Architecture of the tag", + "name": "arch", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.Tag" + } + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_REF: A ref with the given name does not exist for the given repository." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.Tag" + } + } + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}/tags/{tag}": { + "delete": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"write\" level access to the repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Delete a tag for a repository", + "operationId": "DeleteRepoTag", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "tag name", + "name": "tag", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The domain used to push tags to DTR. Must be set to obtain/manipulate Notary related information", + "name": "domain", + "in": "query" + } + ], + "responses": { + "204": { + "description": "success" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_TAG: A tag with the given name does not exist for the given repository." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "409": { + "description": "TAG_IN_NOTARY: This tag is in notary and can't be deleted until it is removed from notary" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}/tags/{tag}/promotion": { + "post": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"read\" level access to the source repository and \"write\" level access to the target repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Promotes a specific tag for a repository", + "operationId": "CreateRepoTagPromotion", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "tag name", + "name": "tag", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.CreatePromotion" + } + } + ], + "responses": { + "201": { + "description": "success", + "schema": { + "$ref": "#/definitions/responses.Promotion" + } + }, + "400": { + "description": "INVALID_TAG_NAME: The given tag name is either too long or contains illegal characters." + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_TAG: A tag with the given name does not exist for the given repository." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}/tags/{tag}/pushMirroring": { + "post": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"read\" level access to the local repository and \"write\" level access to the remote repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Mirrors a local tag by pushing to a remote repository", + "operationId": "CreateRepoTagPushMirroring", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "tag name", + "name": "tag", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.CreateMirroring" + } + } + ], + "responses": { + "201": { + "description": "success", + "schema": { + "$ref": "#/definitions/responses.Mirroring" + } + }, + "400": { + "description": "INVALID_TAG_NAME: The given tag name is either too long or contains illegal characters." + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_TAG: A tag with the given name does not exist for the given repository." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}/teamAccess": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"admin\" level access to the repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "List teams granted access to an organization-owned repository", + "operationId": "ListRepoTeamAccess", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The ID of the first record on the page", + "name": "pageStart", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "Maximum number of results to return", + "name": "pageSize", + "in": "query" + }, + { + "type": "boolean", + "default": false, + "description": "Whether to include the resource count in the response header", + "name": "count", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.ListRepoTeamAccess" + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_REPOSITORY: A repository with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.ListRepoTeamAccess" + } + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}/teamAccess/{teamname}": { + "put": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"admin\" level access to the repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Set a team's access to an orgnization-owned repository", + "operationId": "GrantRepoTeamAccess", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "team name", + "name": "teamname", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.Access" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.ListRepoTeamAccess" + } + }, + "400": { + "description": "the team does not belong to the organization" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_TEAM: A team with the given name does not exist in the organization." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.ListRepoTeamAccess" + } + } + } + }, + "delete": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"admin\" level access to the repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "Revoke a team's acccess to an organization-owned repository", + "operationId": "RevokeRepoTeamAccess", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "team name", + "name": "teamname", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "success or the team is not in the access list or there is no such team in the organization" + }, + "400": { + "description": "the repository is not owned by an organization" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_TEAM: A team with the given name does not exist in the organization." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/repositories/{namespace}/{reponame}/webhooks": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"admin\" level access to the repository.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositories" + ], + "summary": "List the webhook subscriptions for a repository", + "operationId": "ListRepoWebhooks", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of repository", + "name": "reponame", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.Webhook" + } + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_REPOSITORY: A repository with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.Webhook" + } + } + } + } + } + }, + "/api/v0/repositoryNamespaces/{namespace}/teamAccess": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as an admin or a member of the organization.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositoryNamespaces" + ], + "summary": "List teams granted access to an organization-owned namespace of repositories", + "operationId": "ListRepoNamespaceTeamAccess", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The ID of the first record on the page", + "name": "pageStart", + "in": "query" + }, + { + "type": "integer", + "default": 10, + "description": "Maximum number of results to return", + "name": "pageSize", + "in": "query" + }, + { + "type": "boolean", + "default": false, + "description": "Whether to include the resource count in the response header", + "name": "count", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.ListRepoNamespaceTeamAccess" + } + }, + "400": { + "description": "the namespace is not owned by an organization" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_ACCOUNT: An account with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.ListRepoNamespaceTeamAccess" + } + } + } + } + }, + "/api/v0/repositoryNamespaces/{namespace}/teamAccess/{teamname}": { + "get": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"admin\" level\naccess to the namespace or is a member of the team.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositoryNamespaces" + ], + "summary": "Get a team's granted access to an organization-owned namespace of repositories", + "operationId": "GetRepoNamespaceTeamAccess", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "team name", + "name": "teamname", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.NamespaceTeamAccess" + } + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_NAMESPACE_TEAM_ACCESS: An access grant for the given team in the given namespace does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.NamespaceTeamAccess" + } + } + } + }, + "put": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"admin\" level access to the namespace.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositoryNamespaces" + ], + "summary": "Set a team's access to an organization-owned namespace of repositories", + "operationId": "GrantRepoNamespaceTeamAccess", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "team name", + "name": "teamname", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.Access" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.NamespaceTeamAccess" + } + }, + "400": { + "description": "the team does not belong to the owning organization" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_TEAM: A team with the given name does not exist in the organization." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/responses.NamespaceTeamAccess" + } + } + } + }, + "delete": { + "description": "\n*Authorization:* Client must be authenticated as a user who has \"admin\" level access to the namespace.\n\t\t", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "repositoryNamespaces" + ], + "summary": "Revoke a team's access to an organization-owned namespace of repositories", + "operationId": "RevokeRepoNamespaceTeamAccess", + "parameters": [ + { + "type": "string", + "description": "namespace/owner of repository", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "team name", + "name": "teamname", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "success or the team does not exist in the access list or there is no such team in the organization" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_TEAM: A team with the given name does not exist in the organization." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + } + } + } + }, + "/api/v0/webhooks": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "webhooks" + ], + "summary": "List Webhooks", + "operationId": "ListWebhooks", + "parameters": [ + { + "type": "string", + "default": "any", + "description": "The type of webhook to list", + "name": "webhookType", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.Webhook" + } + } + }, + "400": { + "description": "INVALID_JSON: Unable to parse JSON" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.Webhook" + } + } + } + } + }, + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "webhooks" + ], + "summary": "Create Webhook", + "operationId": "CreateWebhook", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.Webhook" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.Webhook" + } + } + }, + "400": { + "description": "INVALID_JSON: Unable to parse JSON" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_ACCOUNT: An account with the given name does not exist." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.Webhook" + } + } + } + } + } + }, + "/api/v0/webhooks/test": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "webhooks" + ], + "summary": "Test Webhook", + "operationId": "TestWebhook", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.WebhookTestPayload" + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "INVALID_JSON: Unable to parse JSON" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK" + } + } + } + }, + "/api/v0/webhooks/update": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "webhooks" + ], + "summary": "Update Webhook", + "operationId": "UpdateWebhook", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/forms.WebhookUpdate" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.Webhook" + } + } + }, + "400": { + "description": "INVALID_JSON: Unable to parse JSON" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.Webhook" + } + } + } + } + } + }, + "/api/v0/webhooks/{webhook}": { + "delete": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "webhooks" + ], + "summary": "Delete Webhook", + "operationId": "DeleteWebhook", + "parameters": [ + { + "type": "string", + "description": "webhook subscription ID", + "name": "webhook", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "NOT_AUTHENTICATED: The client is not authenticated." + }, + "403": { + "description": "NOT_AUTHORIZED: The client is not authorized." + }, + "404": { + "description": "NO_SUCH_WEBHOOK: A webhook subscription with the given name does not exist for the given repository." + }, + "405": { + "description": "NOT_ALLOWED: Method Not Allowed" + }, + "406": { + "description": "NOT_ACCEPTABLE: Not Acceptable" + }, + "415": { + "description": "UNSUPPORTED_MEDIA_TYPE: Unsupported Media Type" + }, + "default": { + "description": "OK" + } + } + } + }, + "/api/v0/workers": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "workers" + ], + "summary": "List all workers", + "operationId": "ListWorkers", + "responses": { + "200": { + "description": "Success, list of workers returned.", + "schema": { + "$ref": "#/definitions/tmpresponses.Workers" + } + }, + "default": { + "description": "Success, list of workers returned.", + "schema": { + "$ref": "#/definitions/tmpresponses.Workers" + } + } + } + } + }, + "/api/v0/workers/{id}/capacity": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "workers" + ], + "summary": "Update the capacity for a worker", + "operationId": "UpdateWorkerCapacity", + "parameters": [ + { + "type": "string", + "description": "ID of worker to update", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/tmpforms.UpdateWorkerCapacity" + } + } + ], + "responses": { + "202": { + "description": "Success." + } + } + } + } + }, + "definitions": { + "forms.Access": { + "required": [ + "accessLevel" + ], + "properties": { + "accessLevel": { + "type": "string", + "enum": [ + "read-only", + "read-write", + "admin" + ] + } + } + }, + "forms.CreateAPIToken": { + "properties": { + "tokenLabel": { + "type": "string" + } + } + }, + "forms.CreateContentCache": { + "required": [ + "name", + "host" + ], + "properties": { + "host": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "forms.CreateMirroring": { + "required": [ + "remoteHost", + "remoteRepository", + "remoteCA", + "skipTLSVerification", + "remoteTag", + "username", + "password", + "authToken" + ], + "properties": { + "authToken": { + "type": "string" + }, + "password": { + "type": "string" + }, + "remoteCA": { + "type": "string" + }, + "remoteHost": { + "type": "string" + }, + "remoteRepository": { + "type": "string" + }, + "remoteTag": { + "type": "string" + }, + "skipTLSVerification": { + "type": "boolean" + }, + "username": { + "type": "string" + } + } + }, + "forms.CreatePollMirroringPolicy": { + "required": [ + "remoteHost", + "remoteRepository", + "remoteCA", + "skipTLSVerification", + "enabled", + "username", + "password", + "authToken" + ], + "properties": { + "authToken": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "password": { + "type": "string" + }, + "remoteCA": { + "type": "string" + }, + "remoteHost": { + "type": "string" + }, + "remoteRepository": { + "type": "string" + }, + "skipTLSVerification": { + "type": "boolean" + }, + "username": { + "type": "string" + } + } + }, + "forms.CreatePromotion": { + "required": [ + "targetRepository", + "targetTag" + ], + "properties": { + "targetRepository": { + "type": "string" + }, + "targetTag": { + "type": "string" + } + } + }, + "forms.CreatePromotionPolicy": { + "required": [ + "rules", + "targetRepository", + "tagTemplate", + "enabled" + ], + "properties": { + "enabled": { + "type": "boolean" + }, + "rules": { + "type": "array", + "items": { + "$ref": "#/definitions/ruleengine.Rule" + } + }, + "tagTemplate": { + "type": "string" + }, + "targetRepository": { + "type": "string" + } + } + }, + "forms.CreatePruningPolicy": { + "required": [ + "rules", + "enabled" + ], + "properties": { + "enabled": { + "type": "boolean" + }, + "rules": { + "type": "array", + "items": { + "$ref": "#/definitions/ruleengine.Rule" + } + } + } + }, + "forms.CreatePushMirroringPolicy": { + "required": [ + "rules", + "remoteHost", + "remoteRepository", + "remoteCA", + "skipTLSVerification", + "tagTemplate", + "enabled", + "username", + "password", + "authToken" + ], + "properties": { + "authToken": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "password": { + "type": "string" + }, + "remoteCA": { + "type": "string" + }, + "remoteHost": { + "type": "string" + }, + "remoteRepository": { + "type": "string" + }, + "rules": { + "type": "array", + "items": { + "$ref": "#/definitions/ruleengine.Rule" + } + }, + "skipTLSVerification": { + "type": "boolean" + }, + "tagTemplate": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "forms.CreateRemoteRegistryCheck": { + "required": [ + "remoteHost", + "remoteRepository", + "remoteCA", + "skipTLSVerification", + "username", + "password", + "authToken" + ], + "properties": { + "authToken": { + "type": "string" + }, + "password": { + "type": "string" + }, + "remoteCA": { + "type": "string" + }, + "remoteHost": { + "type": "string" + }, + "remoteRepository": { + "type": "string" + }, + "skipTLSVerification": { + "type": "boolean" + }, + "username": { + "type": "string" + } + } + }, + "forms.CreateRepo": { + "required": [ + "name", + "shortDescription", + "longDescription", + "scanOnPush", + "immutableTags", + "enableManifestLists", + "tagLimit" + ], + "properties": { + "enableManifestLists": { + "type": "boolean" + }, + "immutableTags": { + "type": "boolean" + }, + "longDescription": { + "type": "string" + }, + "name": { + "type": "string" + }, + "scanOnPush": { + "type": "boolean" + }, + "shortDescription": { + "type": "string" + }, + "tagLimit": { + "type": "integer", + "format": "integer" + }, + "visibility": { + "type": "string", + "enum": [ + "public", + "private" + ] + } + } + }, + "forms.DeleteMirroringPolicyIDs": { + "required": [ + "id" + ], + "properties": { + "id": { + "type": "string" + } + } + }, + "forms.EmptyForm": {}, + "forms.Image": { + "required": [ + "name", + "digest" + ], + "properties": { + "digest": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "forms.ImagesForm": { + "required": [ + "images" + ], + "properties": { + "images": { + "type": "array", + "items": { + "$ref": "#/definitions/forms.Image" + } + } + } + }, + "forms.ScanOptions": { + "required": [ + "scan", + "check" + ], + "properties": { + "check": { + "type": "boolean" + }, + "scan": { + "type": "boolean" + } + } + }, + "forms.Settings": { + "required": [ + "dtrHost", + "sso", + "createRepositoryOnPush", + "disableUpgrades", + "reportAnalytics", + "anonymizeAnalytics", + "disableBackupWarning", + "webTLSCert", + "webTLSKey", + "webTLSCA", + "scanningEnabled", + "scanningSyncOnline", + "scanningDeadline", + "scanningEnableAutoRecheck", + "jobHistoryCompactionEnabled", + "jobHistoryToKeep", + "jobHistoryMaxAge", + "repoEventHistoryCompactionEnabled", + "repoEventHistoryToKeep", + "repoEventHistoryMaxAge", + "readOnlyRegistry" + ], + "properties": { + "anonymizeAnalytics": { + "type": "boolean" + }, + "createRepositoryOnPush": { + "type": "boolean" + }, + "disableBackupWarning": { + "type": "boolean" + }, + "disableUpgrades": { + "type": "boolean" + }, + "dtrHost": { + "type": "string" + }, + "jobHistoryCompactionEnabled": { + "type": "boolean" + }, + "jobHistoryMaxAge": { + "type": "string" + }, + "jobHistoryToKeep": { + "type": "integer", + "format": "int64" + }, + "readOnlyRegistry": { + "type": "boolean" + }, + "repoEventHistoryCompactionEnabled": { + "type": "boolean" + }, + "repoEventHistoryMaxAge": { + "type": "string" + }, + "repoEventHistoryToKeep": { + "type": "integer", + "format": "int64" + }, + "reportAnalytics": { + "type": "boolean" + }, + "scanningDeadline": { + "type": "integer" + }, + "scanningEnableAutoRecheck": { + "type": "boolean" + }, + "scanningEnabled": { + "type": "boolean" + }, + "scanningSyncOnline": { + "type": "boolean" + }, + "sso": { + "type": "boolean" + }, + "webTLSCA": { + "type": "string" + }, + "webTLSCert": { + "type": "string" + }, + "webTLSKey": { + "type": "string" + } + } + }, + "forms.ToggleScanOnPush": { + "required": [ + "scanOnPush" + ], + "properties": { + "scanOnPush": { + "type": "boolean" + } + } + }, + "forms.UpdateAPIToken": { + "properties": { + "isActive": { + "type": "boolean" + }, + "tokenLabel": { + "type": "string" + } + } + }, + "forms.UpdatePollMirroringPolicy": { + "properties": { + "authToken": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "password": { + "type": "string" + }, + "remoteCA": { + "type": "string" + }, + "remoteHost": { + "type": "string" + }, + "remoteRepository": { + "type": "string" + }, + "skipTLSVerification": { + "type": "boolean" + }, + "username": { + "type": "string" + } + } + }, + "forms.UpdatePromotionPolicy": { + "properties": { + "enabled": { + "type": "boolean" + }, + "rules": { + "type": "array", + "items": { + "$ref": "#/definitions/ruleengine.Rule" + } + }, + "tagTemplate": { + "type": "string" + }, + "targetRepository": { + "type": "string" + } + } + }, + "forms.UpdatePruningPolicy": { + "properties": { + "enabled": { + "type": "boolean" + }, + "rules": { + "type": "array", + "items": { + "$ref": "#/definitions/ruleengine.Rule" + } + } + } + }, + "forms.UpdatePushMirroringPolicy": { + "properties": { + "authToken": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "password": { + "type": "string" + }, + "remoteCA": { + "type": "string" + }, + "remoteHost": { + "type": "string" + }, + "remoteRepository": { + "type": "string" + }, + "rules": { + "type": "array", + "items": { + "$ref": "#/definitions/ruleengine.Rule" + } + }, + "skipTLSVerification": { + "type": "boolean" + }, + "tagTemplate": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "forms.UpdateRepo": { + "required": [ + "immutableTags" + ], + "properties": { + "enableManifestLists": { + "type": "boolean" + }, + "immutableTags": { + "type": "boolean" + }, + "longDescription": { + "type": "string" + }, + "scanOnPush": { + "type": "boolean" + }, + "shortDescription": { + "type": "string" + }, + "tagLimit": { + "type": "integer", + "format": "integer" + }, + "visibility": { + "type": "string", + "enum": [ + "public", + "private" + ] + } + } + }, + "forms.UserSettings": { + "properties": { + "contentCacheUUID": { + "type": "string" + } + } + }, + "forms.VulnOverrideOption": { + "required": [ + "component", + "componentVersion", + "cve", + "notes" + ], + "properties": { + "component": { + "type": "string" + }, + "componentVersion": { + "type": "string" + }, + "cve": { + "type": "string" + }, + "notes": { + "type": "string" + } + } + }, + "forms.Webhook": { + "required": [ + "endpoint", + "tlsCert", + "skipTLSVerification" + ], + "properties": { + "endpoint": { + "type": "string" + }, + "key": { + "type": "string" + }, + "skipTLSVerification": { + "type": "boolean" + }, + "tlsCert": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "TAG_PUSH", + "TAG_PULL", + "TAG_DELETE", + "PROMOTION", + "PUSH_MIRRORING", + "POLL_MIRRORING", + "MANIFEST_PUSH", + "MANIFEST_PULL", + "MANIFEST_DELETE", + "REPO_EVENT", + "SCAN_COMPLETED", + "SCAN_FAILED", + "SCANNER_UPDATE_COMPLETED" + ] + } + } + }, + "forms.WebhookTestPayload": { + "required": [ + "type", + "endpoint", + "tlsCert", + "skipTLSVerification" + ], + "properties": { + "endpoint": { + "type": "string" + }, + "skipTLSVerification": { + "type": "boolean" + }, + "tlsCert": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, + "forms.WebhookUpdate": { + "required": [ + "id", + "inactive", + "tlsCert", + "skipTLSVerification" + ], + "properties": { + "id": { + "type": "string" + }, + "inactive": { + "type": "boolean" + }, + "skipTLSVerification": { + "type": "boolean" + }, + "tlsCert": { + "type": "string" + } + } + }, + "responses.APIToken": { + "required": [ + "hashedToken", + "tokenLabel", + "isActive", + "lastUsed", + "createdAt", + "generatedBy", + "creatorUa" + ], + "properties": { + "createdAt": { + "type": "string", + "format": "date-time" + }, + "creatorUa": { + "type": "string" + }, + "generatedBy": { + "type": "string" + }, + "hashedToken": { + "type": "string" + }, + "isActive": { + "type": "boolean" + }, + "lastUsed": { + "type": "string", + "format": "date-time" + }, + "tokenLabel": { + "type": "string" + } + } + }, + "responses.Account": { + "required": [ + "name", + "id", + "fullName", + "isOrg" + ], + "properties": { + "fullName": { + "description": "Full Name of the account", + "type": "string" + }, + "id": { + "description": "ID of the account", + "type": "string" + }, + "isActive": { + "description": "Whether the user is active and can login (users only)", + "type": "boolean" + }, + "isAdmin": { + "description": "Whether the user is a system admin (users only)", + "type": "boolean" + }, + "isImported": { + "description": "Whether the user was imported from an upstream identity provider", + "type": "boolean" + }, + "isOrg": { + "description": "Whether the account is an organization (or user)", + "type": "boolean" + }, + "membersCount": { + "description": "The number of members of the organization", + "type": "integer", + "format": "int32" + }, + "name": { + "description": "Name of the account", + "type": "string" + }, + "teamsCount": { + "description": "The number of teams in the organization", + "type": "integer", + "format": "int32" + } + } + }, + "responses.Alert": { + "required": [ + "message" + ], + "properties": { + "class": { + "type": "string" + }, + "id": { + "type": "string" + }, + "img": { + "type": "string" + }, + "message": { + "type": "string" + }, + "url": { + "type": "string" + } + } + }, + "responses.Autocomplete": { + "properties": { + "accountResults": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.Account" + } + }, + "repositoryResults": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.Repository" + } + } + } + }, + "responses.ClusterStatus": { + "required": [ + "rethink_system_tables", + "replica_health", + "replica_timestamp", + "replica_readonly", + "gc_lock_holder" + ], + "properties": { + "gc_lock_holder": { + "type": "string" + }, + "replica_health": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "replica_readonly": { + "type": "object", + "additionalProperties": { + "type": "boolean" + } + }, + "replica_timestamp": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "rethink_system_tables": { + "type": "object" + } + } + }, + "responses.Component": { + "required": [ + "component", + "version", + "vulns", + "fullpath" + ], + "properties": { + "component": { + "type": "string" + }, + "fullpath": { + "type": "array", + "items": { + "type": "string" + } + }, + "license": { + "$ref": "#/definitions/responses.License" + }, + "version": { + "type": "string" + }, + "vulns": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.VulnerabilityDetails" + } + } + } + }, + "responses.ContentCache": { + "required": [ + "id", + "name", + "host" + ], + "properties": { + "host": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "responses.DetailedSummary": { + "required": [ + "sha256sum" + ], + "properties": { + "components": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.Component" + } + }, + "sha256sum": { + "type": "string" + } + } + }, + "responses.DockerRepository": { + "required": [ + "description", + "is_official", + "is_trusted", + "name", + "star_count" + ], + "properties": { + "description": { + "type": "string" + }, + "is_official": { + "type": "boolean" + }, + "is_trusted": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "star_count": { + "type": "integer", + "format": "int32" + } + } + }, + "responses.DockerSearch": { + "required": [ + "num_results", + "query", + "results" + ], + "properties": { + "num_results": { + "type": "integer", + "format": "int32" + }, + "query": { + "type": "string" + }, + "results": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.DockerRepository" + } + } + } + }, + "responses.DockerfileLine": { + "required": [ + "line", + "layerDigest", + "size", + "isEmpty" + ], + "properties": { + "isEmpty": { + "type": "boolean" + }, + "layerDigest": { + "type": "string" + }, + "line": { + "type": "string" + }, + "mediaType": { + "type": "string" + }, + "size": { + "type": "integer", + "format": "int64" + }, + "urls": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "responses.Events": { + "required": [ + "events" + ], + "properties": { + "events": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.Event" + } + } + } + }, + "responses.Features": { + "required": [ + "scanningEnabled", + "scanningLicensed", + "promotionLicensed", + "mirroringLicensed", + "metadataStoreOptedIn", + "onlineGCEnabled", + "db_version", + "ucpHost" + ], + "properties": { + "db_version": { + "type": "integer", + "format": "int32" + }, + "metadataStoreOptedIn": { + "type": "boolean" + }, + "mirroringLicensed": { + "type": "boolean" + }, + "onlineGCEnabled": { + "type": "boolean" + }, + "promotionLicensed": { + "type": "boolean" + }, + "scanningEnabled": { + "type": "boolean" + }, + "scanningLicensed": { + "type": "boolean" + }, + "ucpHost": { + "type": "string" + } + } + }, + "responses.Language": { + "required": [ + "language" + ], + "properties": { + "language": { + "type": "string" + } + } + }, + "responses.LayerVulnOverride": { + "required": [ + "pk", + "digest", + "component", + "componentVersion", + "cve", + "notes" + ], + "properties": { + "component": { + "type": "string" + }, + "componentVersion": { + "type": "string" + }, + "cve": { + "type": "string" + }, + "digest": { + "type": "string" + }, + "notes": { + "type": "string" + }, + "pk": { + "type": "string" + } + } + }, + "responses.License": { + "required": [ + "name", + "type", + "url" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "url": { + "type": "string" + } + } + }, + "responses.ListRepoNamespaceTeamAccess": { + "required": [ + "namespace", + "teamAccessList" + ], + "properties": { + "namespace": { + "type": "string" + }, + "teamAccessList": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.TeamAccess" + } + } + } + }, + "responses.ListRepoTeamAccess": { + "required": [ + "repository", + "teamAccessList" + ], + "properties": { + "repository": { + "$ref": "#/definitions/responses.Repository" + }, + "teamAccessList": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.TeamAccess" + } + } + } + }, + "responses.ListTag": { + "required": [ + "name", + "digest", + "author", + "updatedAt", + "createdAt", + "hashMismatch", + "inNotary", + "manifest" + ], + "properties": { + "author": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "digest": { + "type": "string" + }, + "hashMismatch": { + "description": "true if the hashes from notary and registry don't match", + "type": "boolean" + }, + "inNotary": { + "description": "true if the tag exists in Notary", + "type": "boolean" + }, + "manifest": { + "$ref": "#/definitions/responses.Manifest" + }, + "mirroring": { + "$ref": "#/definitions/responses.Mirroring" + }, + "name": { + "type": "string" + }, + "promotion": { + "$ref": "#/definitions/responses.Promotion" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + } + }, + "responses.ListTeamRepoAccess": { + "required": [ + "team", + "repositoryAccessList" + ], + "properties": { + "repositoryAccessList": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.RepoAccess" + } + }, + "team": { + "$ref": "#/definitions/responses.Team" + } + } + }, + "responses.Manifest": { + "required": [ + "digest" + ], + "properties": { + "architecture": { + "type": "string" + }, + "author": { + "type": "string" + }, + "configDigest": { + "type": "string" + }, + "configMediaType": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "digest": { + "type": "string" + }, + "dockerfile": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.DockerfileLine" + } + }, + "mediaType": { + "type": "string" + }, + "os": { + "type": "string" + }, + "osVersion": { + "type": "string" + }, + "size": { + "type": "integer", + "format": "int64" + } + } + }, + "responses.Mirroring": { + "required": [ + "mirroringPolicyID", + "digest", + "remoteRepository", + "remoteTag" + ], + "properties": { + "digest": { + "type": "string" + }, + "mirroringPolicyID": { + "type": "string" + }, + "remoteRepository": { + "type": "string" + }, + "remoteTag": { + "type": "string" + } + } + }, + "responses.MirroringPolicy": { + "required": [ + "id", + "mirroringType", + "username", + "localRepository", + "remoteHost", + "remoteRepository", + "remoteCA", + "skipTLSVerification", + "enabled", + "lastMirroredAt", + "lastStatus" + ], + "properties": { + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "lastMirroredAt": { + "type": "string" + }, + "lastStatus": { + "$ref": "#/definitions/schema.MirroringStatus" + }, + "localRepository": { + "type": "string" + }, + "mirroringType": { + "type": "string" + }, + "remoteCA": { + "type": "string" + }, + "remoteHost": { + "type": "string" + }, + "remoteRepository": { + "type": "string" + }, + "rules": { + "type": "array", + "items": { + "$ref": "#/definitions/ruleengine.Rule" + } + }, + "skipTLSVerification": { + "type": "boolean" + }, + "tagTemplate": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "responses.NamespaceTeamAccess": { + "required": [ + "accessLevel", + "team", + "namespace" + ], + "properties": { + "accessLevel": { + "type": "string", + "enum": [ + "read-only", + "read-write", + "admin" + ] + }, + "namespace": { + "type": "string" + }, + "team": { + "$ref": "#/definitions/responses.Team" + } + } + }, + "responses.NautilusStatus": { + "required": [ + "state", + "scanner_version", + "scannerUpdatedAt", + "db_version", + "db_updated_at", + "lastDBUpdateFailed", + "lastVulnOverridesDBUpdateFailed" + ], + "properties": { + "db_updated_at": { + "type": "string", + "format": "date-time" + }, + "db_version": { + "type": "integer", + "format": "int32" + }, + "lastDBUpdateFailed": { + "type": "boolean" + }, + "lastVulnOverridesDBUpdateFailed": { + "type": "boolean" + }, + "replicas": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/schema.ScannerFingerprint" + } + }, + "scannerUpdatedAt": { + "type": "string", + "format": "date-time" + }, + "scanner_version": { + "type": "integer", + "format": "int32" + }, + "state": { + "type": "integer", + "format": "int32" + } + } + }, + "responses.NewAPIToken": { + "required": [ + "token", + "hashedToken", + "tokenLabel", + "isActive", + "lastUsed", + "createdAt", + "generatedBy", + "creatorUa" + ], + "properties": { + "createdAt": { + "type": "string", + "format": "date-time" + }, + "creatorUa": { + "type": "string" + }, + "generatedBy": { + "type": "string" + }, + "hashedToken": { + "type": "string" + }, + "isActive": { + "type": "boolean" + }, + "lastUsed": { + "type": "string", + "format": "date-time" + }, + "token": { + "type": "string" + }, + "tokenLabel": { + "type": "string" + } + } + }, + "responses.Note": { + "required": [ + "reason", + "type" + ], + "properties": { + "reason": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, + "responses.OldScanSummary": { + "required": [ + "namespace", + "reponame", + "tag", + "critical", + "major", + "minor", + "last_scan_status", + "check_completed_at", + "should_rescan", + "has_foreign_layers" + ], + "properties": { + "check_completed_at": { + "type": "string", + "format": "date-time" + }, + "critical": { + "type": "integer", + "format": "int32" + }, + "has_foreign_layers": { + "type": "boolean" + }, + "last_scan_status": { + "type": "integer", + "format": "int32" + }, + "layer_details": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.DetailedSummary" + } + }, + "major": { + "type": "integer", + "format": "int32" + }, + "minor": { + "type": "integer", + "format": "int32" + }, + "namespace": { + "type": "string" + }, + "reponame": { + "type": "string" + }, + "should_rescan": { + "type": "boolean" + }, + "tag": { + "type": "string" + } + } + }, + "responses.PollMirroringPolicy": { + "required": [ + "id", + "username", + "localRepository", + "remoteHost", + "remoteRepository", + "remoteCA", + "skipTLSVerification", + "enabled", + "lastMirroredAt", + "lastStatus" + ], + "properties": { + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "lastMirroredAt": { + "type": "string" + }, + "lastStatus": { + "$ref": "#/definitions/schema.MirroringStatus" + }, + "localRepository": { + "type": "string" + }, + "remoteCA": { + "type": "string" + }, + "remoteHost": { + "type": "string" + }, + "remoteRepository": { + "type": "string" + }, + "skipTLSVerification": { + "type": "boolean" + }, + "username": { + "type": "string" + } + } + }, + "responses.Promotion": { + "required": [ + "promotionPolicyID", + "string", + "sourceRepository", + "sourceTag" + ], + "properties": { + "promotionPolicyID": { + "type": "string" + }, + "sourceRepository": { + "type": "string" + }, + "sourceTag": { + "type": "string" + }, + "string": { + "type": "string" + } + } + }, + "responses.PromotionPolicy": { + "required": [ + "id", + "rules", + "sourceRepository", + "targetRepository", + "tagTemplate", + "enabled", + "lastPromotedAt" + ], + "properties": { + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "lastPromotedAt": { + "type": "string", + "format": "date-time" + }, + "rules": { + "type": "array", + "items": { + "$ref": "#/definitions/ruleengine.Rule" + } + }, + "sourceRepository": { + "type": "string" + }, + "tagTemplate": { + "type": "string" + }, + "targetRepository": { + "type": "string" + } + } + }, + "responses.PruningPolicy": { + "required": [ + "id", + "rules", + "repository", + "enabled", + "lastPrunedAt" + ], + "properties": { + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "lastPrunedAt": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "rules": { + "type": "array", + "items": { + "$ref": "#/definitions/ruleengine.Rule" + } + } + } + }, + "responses.PushMirroringPolicy": { + "required": [ + "id", + "rules", + "username", + "localRepository", + "remoteHost", + "remoteRepository", + "remoteCA", + "skipTLSVerification", + "tagTemplate", + "enabled", + "lastMirroredAt", + "lastStatus" + ], + "properties": { + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "lastMirroredAt": { + "type": "string" + }, + "lastStatus": { + "$ref": "#/definitions/schema.MirroringStatus" + }, + "localRepository": { + "type": "string" + }, + "remoteCA": { + "type": "string" + }, + "remoteHost": { + "type": "string" + }, + "remoteRepository": { + "type": "string" + }, + "rules": { + "type": "array", + "items": { + "$ref": "#/definitions/ruleengine.Rule" + } + }, + "skipTLSVerification": { + "type": "boolean" + }, + "tagTemplate": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "responses.RemoteRegistryCheck": { + "required": [ + "registryType", + "permissions" + ], + "properties": { + "permissions": { + "$ref": "#/definitions/responses.RemoteRepositoryPermissions" + }, + "registryType": { + "type": "string" + } + } + }, + "responses.RemoteRepositoryPermissions": { + "required": [ + "read", + "write" + ], + "properties": { + "read": { + "type": "boolean" + }, + "write": { + "type": "boolean" + } + } + }, + "responses.ReplicaSettings": { + "required": [ + "HTTPPort", + "HTTPSPort", + "node" + ], + "properties": { + "HTTPPort": { + "type": "integer" + }, + "HTTPSPort": { + "type": "integer" + }, + "node": { + "type": "string" + } + } + }, + "responses.RepoAccess": { + "required": [ + "accessLevel", + "repository" + ], + "properties": { + "accessLevel": { + "type": "string", + "enum": [ + "read-only", + "read-write", + "admin" + ] + }, + "repository": { + "$ref": "#/definitions/responses.Repository" + } + } + }, + "responses.RepoUserAccess": { + "required": [ + "accessLevel", + "user", + "repository" + ], + "properties": { + "accessLevel": { + "type": "string", + "enum": [ + "read-only", + "read-write", + "admin" + ] + }, + "repository": { + "$ref": "#/definitions/responses.Repository" + }, + "user": { + "$ref": "#/definitions/responses.Account" + } + } + }, + "responses.Repositories": { + "required": [ + "repositories" + ], + "properties": { + "repositories": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.Repository" + } + } + } + }, + "responses.Repository": { + "required": [ + "id", + "namespace", + "namespaceType", + "name", + "shortDescription", + "visibility", + "scanOnPush", + "immutableTags", + "enableManifestLists", + "pulls", + "pushes", + "tagLimit" + ], + "properties": { + "enableManifestLists": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "immutableTags": { + "type": "boolean" + }, + "longDescription": { + "type": "string" + }, + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "namespaceType": { + "type": "string", + "enum": [ + "user", + "organization" + ] + }, + "pulls": { + "type": "integer", + "format": "integer" + }, + "pushes": { + "type": "integer", + "format": "integer" + }, + "scanOnPush": { + "type": "boolean" + }, + "shortDescription": { + "type": "string" + }, + "tagLimit": { + "type": "integer", + "format": "integer" + }, + "visibility": { + "type": "string", + "enum": [ + "public", + "private" + ] + } + } + }, + "responses.ScanSummary": { + "required": [ + "scannedImage", + "shouldRescan" + ], + "properties": { + "scanStatus": { + "type": "integer", + "format": "int32" + }, + "scannedImage": { + "$ref": "#/definitions/schema.ScannedImage" + }, + "shouldRescan": { + "type": "boolean" + } + } + }, + "responses.Settings": { + "required": [ + "dtrHost", + "sso", + "createRepositoryOnPush", + "replicaSettings", + "httpProxy", + "httpsProxy", + "noProxy", + "disableUpgrades", + "reportAnalytics", + "anonymizeAnalytics", + "disableBackupWarning", + "logProtocol", + "logHost", + "logLevel", + "webTLSCert", + "webTLSCA", + "replicaID", + "scanningEnabled", + "scanningSyncOnline", + "scanningDeadline", + "scanningEnableAutoRecheck", + "jobHistoryCompactionEnabled", + "jobHistoryToKeep", + "jobHistoryMaxAge", + "repoEventHistoryCompactionEnabled", + "repoEventHistoryToKeep", + "repoEventHistoryMaxAge", + "storageVolume", + "nfsHost", + "nfsPath", + "readOnlyRegistry" + ], + "properties": { + "anonymizeAnalytics": { + "type": "boolean" + }, + "createRepositoryOnPush": { + "type": "boolean" + }, + "disableBackupWarning": { + "type": "boolean" + }, + "disableUpgrades": { + "type": "boolean" + }, + "dtrHost": { + "type": "string" + }, + "httpProxy": { + "type": "string" + }, + "httpsProxy": { + "type": "string" + }, + "jobHistoryCompactionEnabled": { + "type": "boolean" + }, + "jobHistoryMaxAge": { + "type": "string" + }, + "jobHistoryToKeep": { + "type": "integer", + "format": "int64" + }, + "logHost": { + "type": "string" + }, + "logLevel": { + "type": "string" + }, + "logProtocol": { + "type": "string" + }, + "nfsHost": { + "type": "string" + }, + "nfsPath": { + "type": "string" + }, + "noProxy": { + "type": "string" + }, + "readOnlyRegistry": { + "type": "boolean" + }, + "replicaID": { + "type": "string" + }, + "replicaSettings": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/responses.ReplicaSettings" + } + }, + "repoEventHistoryCompactionEnabled": { + "type": "boolean" + }, + "repoEventHistoryMaxAge": { + "type": "string" + }, + "repoEventHistoryToKeep": { + "type": "integer", + "format": "int64" + }, + "reportAnalytics": { + "type": "boolean" + }, + "scanningDeadline": { + "type": "integer" + }, + "scanningEnableAutoRecheck": { + "type": "boolean" + }, + "scanningEnabled": { + "type": "boolean" + }, + "scanningSyncOnline": { + "type": "boolean" + }, + "sso": { + "type": "boolean" + }, + "storageVolume": { + "type": "string" + }, + "webTLSCA": { + "type": "string" + }, + "webTLSCert": { + "type": "string" + } + } + }, + "responses.Tag": { + "required": [ + "digest", + "createdAt", + "inNotary", + "manifest", + "name", + "author", + "updatedAt", + "hashMismatch" + ], + "properties": { + "author": { + "type": "string" + }, + "components": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.ScannerComponent" + } + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "digest": { + "type": "string" + }, + "hashMismatch": { + "description": "true if the hashes from notary and registry don't match", + "type": "boolean" + }, + "inNotary": { + "description": "true if the tag exists in Notary", + "type": "boolean" + }, + "licenses": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.ScannerLicense" + } + }, + "manifest": { + "$ref": "#/definitions/responses.Manifest" + }, + "mirroring": { + "$ref": "#/definitions/responses.Mirroring" + }, + "name": { + "type": "string" + }, + "promotion": { + "$ref": "#/definitions/responses.Promotion" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + }, + "vuln_summary": { + "$ref": "#/definitions/responses.OldScanSummary" + } + } + }, + "responses.Team": { + "required": [ + "id", + "clientUserIsMember" + ], + "properties": { + "clientUserIsMember": { + "type": "boolean" + }, + "id": { + "type": "string" + } + } + }, + "responses.TeamAccess": { + "required": [ + "accessLevel", + "team" + ], + "properties": { + "accessLevel": { + "type": "string", + "enum": [ + "read-only", + "read-write", + "admin" + ] + }, + "team": { + "$ref": "#/definitions/responses.Team" + } + } + }, + "responses.ThinScanSummaries": { + "required": [ + "images" + ], + "properties": { + "images": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/schema.ScannerVulnCount" + } + } + } + }, + "responses.ThinTag": { + "required": [ + "name", + "digest" + ], + "properties": { + "digest": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "responses.UserSettings": { + "required": [ + "ContentCacheUUID" + ], + "properties": { + "ContentCacheUUID": { + "type": "string" + } + } + }, + "responses.Vulnerability": { + "required": [ + "cve", + "cvss", + "summary" + ], + "properties": { + "cve": { + "type": "string" + }, + "cvss": { + "type": "number", + "format": "float" + }, + "summary": { + "type": "string" + } + } + }, + "responses.VulnerabilityDetails": { + "required": [ + "vuln", + "exact", + "notes" + ], + "properties": { + "exact": { + "type": "boolean" + }, + "notes": { + "type": "array", + "items": { + "$ref": "#/definitions/responses.Note" + } + }, + "vuln": { + "$ref": "#/definitions/responses.Vulnerability" + } + } + }, + "responses.Webhook": { + "required": [ + "id", + "type", + "key", + "endpoint", + "authorID", + "createdAt", + "inactive", + "tlsCert", + "skipTLSVerification" + ], + "properties": { + "authorID": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "endpoint": { + "type": "string" + }, + "id": { + "type": "string" + }, + "inactive": { + "type": "boolean" + }, + "key": { + "type": "string" + }, + "lastSuccessfulAt": { + "type": "string", + "format": "date-time" + }, + "skipTLSVerification": { + "type": "boolean" + }, + "tlsCert": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, + "ruleengine.Rule": { + "properties": { + "field": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "values": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "schema.Event": { + "required": [ + "id", + "publishedAt", + "actor", + "actorType", + "type", + "object", + "repository" + ], + "properties": { + "actor": { + "type": "string" + }, + "actorType": { + "type": "string" + }, + "id": { + "type": "string" + }, + "object": { + "$ref": "#/definitions/schema.Object" + }, + "publishedAt": { + "type": "string", + "format": "date-time" + }, + "repository": { + "type": "string" + }, + "target": { + "$ref": "#/definitions/schema.Object" + }, + "type": { + "type": "string" + } + } + }, + "schema.LayerVulnOverride": { + "required": [ + "pk", + "digest", + "component", + "componentVersion", + "cve", + "notes" + ], + "properties": { + "component": { + "type": "string" + }, + "componentVersion": { + "type": "string" + }, + "cve": { + "type": "string" + }, + "digest": { + "type": "string" + }, + "notes": { + "type": "string" + }, + "pk": { + "type": "string" + } + } + }, + "schema.MirroringStatus": { + "required": [ + "code", + "detail", + "timestamp" + ], + "properties": { + "code": { + "type": "string" + }, + "detail": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + } + } + }, + "schema.Object": { + "required": [ + "id", + "type" + ], + "properties": { + "content": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, + "schema.ScannedImage": { + "required": [ + "pk", + "namespace", + "repository", + "tag", + "manifestDigest", + "totalVulnCount", + "licenses", + "layers", + "components", + "cves", + "maxCVSSValue", + "scannerFingerprint", + "vulnOverrides" + ], + "properties": { + "components": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.ScannerComponent" + } + }, + "cves": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.ScannerCVE" + } + }, + "layers": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.ScannerLayer" + } + }, + "licenses": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.ScannerLicense" + } + }, + "manifestDigest": { + "type": "string" + }, + "maxCVSSValue": { + "type": "number", + "format": "float" + }, + "namespace": { + "type": "string" + }, + "pk": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "scannerFingerprint": { + "$ref": "#/definitions/schema.ScannerFingerprint" + }, + "tag": { + "type": "string" + }, + "totalVulnCount": { + "$ref": "#/definitions/schema.ScannerVulnCount" + }, + "vulnOverrides": { + "type": "array", + "items": { + "$ref": "#/definitions/schema.LayerVulnOverride" + } + } + } + }, + "schema.ScannerCVE": { + "required": [ + "cvePK", + "summary", + "cvss", + "notes" + ], + "properties": { + "cvePK": { + "type": "string" + }, + "cvss": { + "type": "number", + "format": "float" + }, + "notes": { + "type": "string" + }, + "summary": { + "type": "string" + } + } + }, + "schema.ScannerComponent": { + "required": [ + "componentPK", + "vulnCount", + "name", + "version", + "filepaths", + "cves", + "licenses", + "source" + ], + "properties": { + "componentPK": { + "type": "string" + }, + "cves": { + "type": "array", + "items": { + "type": "string" + } + }, + "filepaths": { + "type": "array", + "items": { + "type": "string" + } + }, + "licenses": { + "type": "array", + "items": { + "type": "string" + } + }, + "name": { + "type": "string" + }, + "source": { + "type": "string" + }, + "version": { + "type": "string" + }, + "vulnCount": { + "$ref": "#/definitions/schema.ScannerVulnCount" + } + } + }, + "schema.ScannerFingerprint": { + "required": [ + "scannerType", + "version" + ], + "properties": { + "scannerType": { + "type": "integer", + "format": "int32" + }, + "version": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "schema.ScannerLayer": { + "required": [ + "digest", + "mediaType", + "author", + "size", + "components" + ], + "properties": { + "author": { + "type": "string" + }, + "components": { + "type": "array", + "items": { + "type": "string" + } + }, + "digest": { + "type": "string" + }, + "mediaType": { + "type": "string" + }, + "size": { + "type": "integer", + "format": "int64" + } + } + }, + "schema.ScannerLicense": { + "required": [ + "name", + "url", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "url": { + "type": "string" + } + } + }, + "schema.ScannerVulnCount": { + "required": [ + "critical", + "major", + "minor" + ], + "properties": { + "critical": { + "type": "integer", + "format": "int32" + }, + "major": { + "type": "integer", + "format": "int32" + }, + "minor": { + "type": "integer", + "format": "int32" + } + } + }, + "tmpforms.ActionConfigCreate": { + "required": [ + "action", + "parameters" + ], + "properties": { + "action": { + "description": "The action to modify the config for", + "type": "string" + }, + "parameters": { + "description": "Extra parameters to pass to the job. The available parameters depend on the job. These are overwritten by any corresponding parameters set in the job itself.", + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "tmpforms.CronCreate": { + "required": [ + "action", + "schedule", + "retries", + "capacityMap", + "parameters", + "deadline", + "stopTimeout" + ], + "properties": { + "action": { + "description": "The action which the cron will perform", + "type": "string" + }, + "capacityMap": { + "description": "The map of required capacity", + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "deadline": { + "description": "After this amount of time has passed, a SIGTERM will be sent", + "type": "string" + }, + "parameters": { + "description": "Extra parameters to pass to the job. The available parameters depend on the job.", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "retries": { + "description": "The number of times to retry a job if it fails", + "type": "integer", + "format": "int32" + }, + "schedule": { + "description": "The for the cron as a cronspec string: (seconds) (minutes) (hours) (day of month) (month) (day of week) or @hourly, @weekly, etc.", + "type": "string" + }, + "stopTimeout": { + "description": "This long after SIGTERM is sent, SIGKILL will be sent if the proccess is still alive", + "type": "string" + } + } + }, + "tmpforms.EmptyForm": {}, + "tmpforms.JobSubmission": { + "required": [ + "action", + "parameters", + "retries", + "capacityMap", + "deadline", + "stopTimeout", + "scheduledAt" + ], + "properties": { + "action": { + "description": "The action which the job will perform", + "type": "string" + }, + "capacityMap": { + "description": "The map of required capacity", + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "deadline": { + "description": "After this amount of time has passed, a SIGTERM will be sent", + "type": "string" + }, + "parameters": { + "description": "Parameters to start the job with", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "retries": { + "description": "The number of times to retry a job if it fails", + "type": "integer", + "format": "int32" + }, + "scheduledAt": { + "description": "The time at which to run the job. Empty string or no value means now. Format: RFC3339", + "type": "string" + }, + "stopTimeout": { + "description": "This long after SIGTERM is sent, SIGKILL will be sent if the proccess is still alive", + "type": "string" + } + } + }, + "tmpforms.UpdateWorkerCapacity": { + "required": [ + "capacityMap" + ], + "properties": { + "capacityMap": { + "description": "The new capacity for the worker, representing roughly the amount of RAM to use", + "type": "object", + "additionalProperties": { + "type": "integer" + } + } + } + }, + "tmpresponses.ActionConfig": { + "required": [ + "id", + "action", + "parameters" + ], + "properties": { + "action": { + "description": "The action this config refers to.", + "type": "string" + }, + "id": { + "description": "Randomly generated UUID for foreign references.", + "type": "string" + }, + "parameters": { + "description": "Extra parameters to pass to the job. The available parameters depend on the job.", + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "tmpresponses.ActionConfigs": { + "required": [ + "actionConfigs" + ], + "properties": { + "actionConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/tmpresponses.ActionConfig" + } + } + } + }, + "tmpresponses.Cron": { + "required": [ + "id", + "action", + "schedule", + "retries", + "capacityMap", + "parameters", + "deadline", + "stopTimeout", + "nextRun" + ], + "properties": { + "action": { + "description": "The action to be performed by jobs spawned from this cron.", + "type": "string" + }, + "capacityMap": { + "description": "The map of required capacity", + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "deadline": { + "type": "string" + }, + "id": { + "description": "Randomly generated UUID for foreign references.", + "type": "string" + }, + "nextRun": { + "description": "The next time the job will run.", + "type": "string", + "format": "date-time" + }, + "parameters": { + "description": "Extra parameters to pass to the job. The available parameters depend on the job.", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "retries": { + "description": "The number of times to retry the job if it fails", + "type": "integer", + "format": "int32" + }, + "schedule": { + "description": "The schedule for this cron as a cronspec string: (seconds) (minutes) (hours) (day of month) (month) (day of week) or @hourly, @weekly, etc.", + "type": "string" + }, + "stopTimeout": { + "description": "This long after SIGTERM is sent, SIGKILL will be sent if the proccess is still alive", + "type": "string" + } + } + }, + "tmpresponses.Crons": { + "required": [ + "crons" + ], + "properties": { + "crons": { + "type": "array", + "items": { + "$ref": "#/definitions/tmpresponses.Cron" + } + } + } + }, + "tmpresponses.Job": { + "required": [ + "id", + "retryFromID", + "workerID", + "status", + "scheduledAt", + "lastUpdated", + "action", + "retriesLeft", + "retriesTotal", + "capacityMap", + "parameters", + "deadline", + "stopTimeout" + ], + "properties": { + "action": { + "description": "The action this job performs", + "type": "string" + }, + "capacityMap": { + "description": "The map of required capacity", + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "deadline": { + "type": "string" + }, + "id": { + "description": "The ID of the job", + "type": "string" + }, + "lastUpdated": { + "description": "The last time at which the status of this job was updated", + "type": "string", + "format": "date-time" + }, + "parameters": { + "description": "Extra parameters to pass to the job. The available parameters depend on the job.", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "retriesLeft": { + "description": "The number of times to retry the job if it fails", + "type": "integer", + "format": "int32" + }, + "retriesTotal": { + "description": "The total number of times to retry the original job if it fails", + "type": "integer", + "format": "int32" + }, + "retryFromID": { + "description": "The ID of the job this job retried from", + "type": "string" + }, + "scheduledAt": { + "description": "The time at which this job was scheduled", + "type": "string", + "format": "date-time" + }, + "status": { + "description": "The current status of the job", + "type": "string", + "enum": [ + "waiting", + "running", + "done", + "canceled", + "errored" + ] + }, + "stopTimeout": { + "description": "This long after SIGTERM is sent, SIGKILL will be sent if the proccess is still alive", + "type": "string" + }, + "workerID": { + "description": "The ID of the worker which performed the job, unclaimed by a worker if empty", + "type": "string" + } + } + }, + "tmpresponses.JobLog": { + "required": [ + "data", + "lineNum" + ], + "properties": { + "data": { + "type": "string" + }, + "lineNum": { + "type": "integer", + "format": "int32" + } + } + }, + "tmpresponses.Jobs": { + "required": [ + "jobs" + ], + "properties": { + "jobs": { + "type": "array", + "items": { + "$ref": "#/definitions/tmpresponses.Job" + } + } + } + }, + "tmpresponses.Worker": { + "required": [ + "id", + "status", + "capacityMap", + "heartbeatExpiration" + ], + "properties": { + "capacityMap": { + "description": "A map used to represent now much load the worker should be allocated. Only security scanning jobs use this and the value is roughly equivalent to expected memory usage in bytes.", + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "heartbeatExpiration": { + "description": "Time after which the worker should be considered dead.", + "type": "string" + }, + "id": { + "description": "Randomly generated UUID for foreign references.", + "type": "string" + }, + "status": { + "description": "Status of the worker", + "type": "string" + } + } + }, + "tmpresponses.Workers": { + "required": [ + "workers" + ], + "properties": { + "workers": { + "type": "array", + "items": { + "$ref": "#/definitions/tmpresponses.Worker" + } + } + } + } + }, + "tags": [ + { + "description": "Accounts", + "name": "accounts" + }, + { + "description": "Admin", + "name": "meta" + }, + { + "description": "Content Caches", + "name": "content_caches" + }, + { + "description": "Repositories", + "name": "repositories" + }, + { + "description": "Repository Namespaces", + "name": "repositoryNamespaces" + }, + { + "description": "Events", + "name": "events" + }, + { + "description": "Docker Security Scanner", + "name": "imagescan" + }, + { + "description": "Webhooks", + "name": "webhooks" + }, + { + "description": "Jobs", + "name": "jobs" + }, + { + "description": "Crons", + "name": "crons" + }, + { + "description": "Workers", + "name": "workers" + }, + { + "description": "Action Configs", + "name": "action_configs" + } + ] +} From 92777eaf4e4e430b79c8c31728c2be05e5a691eb Mon Sep 17 00:00:00 2001 From: paigehargrave Date: Wed, 13 Feb 2019 14:40:23 -0500 Subject: [PATCH 06/23] Update plan-installation.md --- datacenter/ucp/3.0/guides/admin/install/plan-installation.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/datacenter/ucp/3.0/guides/admin/install/plan-installation.md b/datacenter/ucp/3.0/guides/admin/install/plan-installation.md index 04ea8b586c..31c76402f0 100644 --- a/datacenter/ucp/3.0/guides/admin/install/plan-installation.md +++ b/datacenter/ucp/3.0/guides/admin/install/plan-installation.md @@ -40,6 +40,10 @@ Docker UCP requires each node on the cluster to have a static IP address. Before installing UCP, ensure your network and nodes are configured to support this. +## Avoid IP range conflicts + +The `service-cluster-ip-range` API Server flag is currently set to 10.96.0.0/16 and cannot be changed. + ## Time synchronization In distributed systems like Docker UCP, time synchronization is critical From 6eb5ad7aca5b9b01ce9d190fb415e5397ae7647b Mon Sep 17 00:00:00 2001 From: Maria Bermudez Date: Wed, 13 Feb 2019 11:52:38 -0800 Subject: [PATCH 07/23] Fix syntax for IP range --- datacenter/ucp/3.0/guides/admin/install/plan-installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datacenter/ucp/3.0/guides/admin/install/plan-installation.md b/datacenter/ucp/3.0/guides/admin/install/plan-installation.md index 31c76402f0..0ca443f90a 100644 --- a/datacenter/ucp/3.0/guides/admin/install/plan-installation.md +++ b/datacenter/ucp/3.0/guides/admin/install/plan-installation.md @@ -42,7 +42,7 @@ this. ## Avoid IP range conflicts -The `service-cluster-ip-range` API Server flag is currently set to 10.96.0.0/16 and cannot be changed. +The `service-cluster-ip-range` API Server flag is currently set to `10.96.0.0/16` and cannot be changed. ## Time synchronization From b4e4559f8be151474207d5482d67a5cff177d7e9 Mon Sep 17 00:00:00 2001 From: Maria Bermudez Date: Wed, 13 Feb 2019 11:52:59 -0800 Subject: [PATCH 08/23] Fix syntax for IP range --- ee/ucp/admin/install/plan-installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ee/ucp/admin/install/plan-installation.md b/ee/ucp/admin/install/plan-installation.md index 0426126fd2..27195a9b05 100644 --- a/ee/ucp/admin/install/plan-installation.md +++ b/ee/ucp/admin/install/plan-installation.md @@ -42,7 +42,7 @@ this. ## Avoid IP range conflicts -The `service-cluster-ip-range` API Server flag is currently set to 10.96.0.0/16 and cannot be changed. +The `service-cluster-ip-range` API Server flag is currently set to `10.96.0.0/16` and cannot be changed. Swarm uses a default address pool of `10.0.0.0/16` for its overlay networks. If this conflicts with your current network implementation, please use a custom IP address pool. To specify a custom IP address pool, use the `--default-address-pool` command line option during [Swarm initialization](../../../../engine/swarm/swarm-mode.md). From 86086633abc07f91cc6e8f658c37f981075ae663 Mon Sep 17 00:00:00 2001 From: Maria Bermudez Date: Wed, 13 Feb 2019 12:25:40 -0800 Subject: [PATCH 09/23] Fixes 7984 --- ee/ucp/kubernetes/configure-aws-storage.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ee/ucp/kubernetes/configure-aws-storage.md b/ee/ucp/kubernetes/configure-aws-storage.md index 0a5f4b7d88..3976d49589 100644 --- a/ee/ucp/kubernetes/configure-aws-storage.md +++ b/ee/ucp/kubernetes/configure-aws-storage.md @@ -32,8 +32,8 @@ Instances must have the following [AWS Identity and Access Management](https://d ### Infrastructure Configuration - Apply the roles and policies to Kubernetes masters and workers as indicated in the above chart. -- EC2 instances must be set to the private DNS hostname of the instance (will typically end in `.internal`) -- EC2 instances must also be labeled with the key `KubernetesCluster` with a matching value across all nodes. +- Set the hostname of the EC2 instances to the private DNS hostname of the instance. See [DNS Hostnames](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html#vpc-dns-hostnames) and [To change the system hostname without a public DNS name](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/set-hostname.html#set-hostname-system) for more details. +- Label the EC2 instances with the key `KubernetesCluster` and assign the same value across all nodes. ### Cluster Configuration From d4b0b09c791d5bd8aef189ea0fb17c4502af5620 Mon Sep 17 00:00:00 2001 From: Maria Bermudez Date: Wed, 13 Feb 2019 13:11:12 -0800 Subject: [PATCH 10/23] Fixes 964 --- ee/ucp/authorization/group-resources.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ee/ucp/authorization/group-resources.md b/ee/ucp/authorization/group-resources.md index ff43863a9a..07e534362b 100644 --- a/ee/ucp/authorization/group-resources.md +++ b/ee/ucp/authorization/group-resources.md @@ -40,7 +40,9 @@ can be nested inside one another, to create hierarchies. You can nest collections inside one another. If a user is granted permissions for one collection, they'll have permissions for its child collections, -pretty much like a directory structure.. +pretty much like a directory structure. + +![](../images/nested-collection.png){: .with-border} For a child collection, or for a user who belongs to more than one team, the system concatenates permissions from multiple roles into an "effective role" for From e71cd9c2f4095a36160b5c5dedd1f120248742d5 Mon Sep 17 00:00:00 2001 From: Maria Bermudez Date: Wed, 13 Feb 2019 13:12:20 -0800 Subject: [PATCH 11/23] Add nested collection diagram --- nested-collection.png | Bin 0 -> 37867 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 nested-collection.png diff --git a/nested-collection.png b/nested-collection.png new file mode 100644 index 0000000000000000000000000000000000000000..6da26776465527d05f53ed39a7bddfb562a40021 GIT binary patch literal 37867 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 BOicg) literal 0 HcmV?d00001 From dfabcf810910079511828293155806611c94d569 Mon Sep 17 00:00:00 2001 From: Darwin Traver Date: Wed, 13 Feb 2019 16:18:41 -0500 Subject: [PATCH 12/23] Updated UCP rethinkDB default cache size --- ee/ucp/admin/configure/ucp-configuration-file.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ee/ucp/admin/configure/ucp-configuration-file.md b/ee/ucp/admin/configure/ucp-configuration-file.md index 2af248e983..bca7d50e65 100644 --- a/ee/ucp/admin/configure/ucp-configuration-file.md +++ b/ee/ucp/admin/configure/ucp-configuration-file.md @@ -181,7 +181,7 @@ components. Assigning these values overrides the settings in a container's | `metrics_retention_time` | no | Adjusts the metrics retention time. | | `metrics_scrape_interval` | no | Sets the interval for how frequently managers gather metrics from nodes in the cluster. | | `metrics_disk_usage_interval` | no | Sets the interval for how frequently storage metrics are gathered. This operation can be expensive when large volumes are present. | -| `rethinkdb_cache_size` | no | Sets the size of the cache used by UCP's RethinkDB servers. The default is 512MB, but leaving this field empty or specifying `auto` instructs RethinkDB to determine a cache size automatically. | +| `rethinkdb_cache_size` | no | Sets the size of the cache used by UCP's RethinkDB servers. The default is 1GB, but leaving this field empty or specifying `auto` instructs RethinkDB to determine a cache size automatically. | | `cloud_provider` | no | Set the cloud provider for the kubernetes cluster. | | `pod_cidr` | yes | Sets the subnet pool from which the IP for the Pod should be allocated from the CNI ipam plugin. Default is `192.168.0.0/16`. | | `calico_mtu` | no | Set the MTU (maximum transmission unit) size for the Calico plugin. | From 713b90f470af6fe5c5d9e49350ec5b4ba268cf3c Mon Sep 17 00:00:00 2001 From: Maria Bermudez Date: Wed, 13 Feb 2019 13:27:19 -0800 Subject: [PATCH 13/23] Update nested collection deprecation message --- ee/ucp/release-notes.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ee/ucp/release-notes.md b/ee/ucp/release-notes.md index 7e7c15c0e9..1f23ab557f 100644 --- a/ee/ucp/release-notes.md +++ b/ee/ucp/release-notes.md @@ -192,7 +192,9 @@ There are several backward-incompatible changes in the Kubernetes API that may a The following features are deprecated in UCP 3.1. * Collections - * User-created nested collections more than 2 layers deep within the root `/Swarm/` collection are deprecated and will be removed in future versions of the product. In the future, we recommend that at most only two levels of collections be created within UCP under the shared Cluster collection designated as `/Swarm/`. For example, if a production collection is created as a collection under the cluster collection `/Swarm/` as `/Swarm/production/` then at most one level of nestedness should be created, as in `/Swarm/production/app/`. + * The ability to create a nested collection of more than 2 layers deep within the root `/Swarm/` collection is now deprecated and will not be included in future versions of the product. However, current nested collections with more than 2 layers are still retained. + + * Docker recommends a maximum of two layers when creating collections within UCP under the shared cluster collection designated as `/Swarm/`. For example, if a production collection called `/Swarm/production` is created under the shared cluster collection, `/Swarm/`, then only one level of nesting should be created: `/Swarm/production/app/`. See [Nested Collections](/ee/ucp/authorization/group-resources/#nested-collections) for more details. * Kubernetes * **PersistentVolumeLabel** admission controller is deprecated in Kubernetes 1.11. This functionality will be migrated to [Cloud Controller Manager](https://kubernetes.io/docs/tasks/administer-cluster/running-cloud-controller/](https://kubernetes.io/docs/tasks/administer-cluster/running-cloud-controller/) From a638a56e6582865e7156256008175b6cceedfef8 Mon Sep 17 00:00:00 2001 From: Maria Bermudez Date: Wed, 13 Feb 2019 13:32:18 -0800 Subject: [PATCH 14/23] Add files via upload --- ee/ucp/images/nested-collection.png | Bin 0 -> 37867 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 ee/ucp/images/nested-collection.png diff --git a/ee/ucp/images/nested-collection.png b/ee/ucp/images/nested-collection.png new file mode 100644 index 0000000000000000000000000000000000000000..6da26776465527d05f53ed39a7bddfb562a40021 GIT binary patch literal 37867 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 BOicg) literal 0 HcmV?d00001 From 8077a929ab4d6cd0081a9fc445991d8ec8f8777a Mon Sep 17 00:00:00 2001 From: Maria Bermudez Date: Wed, 13 Feb 2019 13:32:47 -0800 Subject: [PATCH 15/23] Add overview for deprecated feature and recommended approach --- ee/ucp/authorization/group-resources.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ee/ucp/authorization/group-resources.md b/ee/ucp/authorization/group-resources.md index 07e534362b..ae029168ec 100644 --- a/ee/ucp/authorization/group-resources.md +++ b/ee/ucp/authorization/group-resources.md @@ -40,7 +40,12 @@ can be nested inside one another, to create hierarchies. You can nest collections inside one another. If a user is granted permissions for one collection, they'll have permissions for its child collections, -pretty much like a directory structure. +pretty much like a directory structure. As of UCP `3.1`, the ability to create a nested +collection of more than 2 layers deep within the root /Swarm/ collection has been deprecated. + +The following image provides two examples of nested collections with the recommended maximum +of two nesting layers. The first example illustrates an environment-oriented collection, and the second +example illustrates an application-oriented collection. ![](../images/nested-collection.png){: .with-border} From 0af8dbf17aca7969b6ef6f2354bc2e9a8e3ec51f Mon Sep 17 00:00:00 2001 From: Maria Bermudez Date: Wed, 13 Feb 2019 13:35:21 -0800 Subject: [PATCH 16/23] Formatting fixes --- ee/ucp/authorization/group-resources.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ee/ucp/authorization/group-resources.md b/ee/ucp/authorization/group-resources.md index ae029168ec..67f3fdbad4 100644 --- a/ee/ucp/authorization/group-resources.md +++ b/ee/ucp/authorization/group-resources.md @@ -41,9 +41,9 @@ can be nested inside one another, to create hierarchies. You can nest collections inside one another. If a user is granted permissions for one collection, they'll have permissions for its child collections, pretty much like a directory structure. As of UCP `3.1`, the ability to create a nested -collection of more than 2 layers deep within the root /Swarm/ collection has been deprecated. +collection of more than 2 layers deep within the root `/Swarm/` collection has been deprecated. -The following image provides two examples of nested collections with the recommended maximum +The following image provides two examples of nested collections with the recommended maximum of two nesting layers. The first example illustrates an environment-oriented collection, and the second example illustrates an application-oriented collection. From 96cc943c949c58807c6876733a9355bee3f44494 Mon Sep 17 00:00:00 2001 From: Maria Bermudez Date: Wed, 13 Feb 2019 14:05:12 -0800 Subject: [PATCH 17/23] Fixes 785 --- ee/ucp/admin/configure/ucp-configuration-file.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ee/ucp/admin/configure/ucp-configuration-file.md b/ee/ucp/admin/configure/ucp-configuration-file.md index 2af248e983..bbf36fcd12 100644 --- a/ee/ucp/admin/configure/ucp-configuration-file.md +++ b/ee/ucp/admin/configure/ucp-configuration-file.md @@ -112,6 +112,8 @@ Configures audit logging options for UCP components. Specifies scheduling options and the default orchestrator for new nodes. +> **Note**: If you run the `kubectl` command, such as `kubectl describe nodes`, to view scheduling rules on Kubernetes nodes, it does not reflect what is configured in UCP Admin settings. UCP uses taints to control container scheduling on nodes and is unrelated to kubectl's `Unschedulable` boolean flag. + | Parameter | Required | Description | |:------------------------------|:---------|:-------------------------------------------------------------------------------------------------------------------------------------------| | `enable_admin_ucp_scheduling` | no | Set to `true` to allow admins to schedule on containers on manager nodes. The default is `false`. | From 6ec6e05bdef98d93993f1bfcddf1511a2c23121a Mon Sep 17 00:00:00 2001 From: Maria Bermudez Date: Wed, 13 Feb 2019 14:10:13 -0800 Subject: [PATCH 18/23] Remove duplicate image --- nested-collection.png | Bin 37867 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 nested-collection.png diff --git a/nested-collection.png b/nested-collection.png deleted file mode 100644 index 6da26776465527d05f53ed39a7bddfb562a40021..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37867 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 BOicg) From bb16b65655e0d886b7889f80b1f1d377a50d1140 Mon Sep 17 00:00:00 2001 From: paigehargrave Date: Wed, 13 Feb 2019 17:10:25 -0500 Subject: [PATCH 19/23] Minor wording tweak --- ee/ucp/kubernetes/configure-aws-storage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ee/ucp/kubernetes/configure-aws-storage.md b/ee/ucp/kubernetes/configure-aws-storage.md index 3976d49589..179edc536c 100644 --- a/ee/ucp/kubernetes/configure-aws-storage.md +++ b/ee/ucp/kubernetes/configure-aws-storage.md @@ -33,7 +33,7 @@ Instances must have the following [AWS Identity and Access Management](https://d - Apply the roles and policies to Kubernetes masters and workers as indicated in the above chart. - Set the hostname of the EC2 instances to the private DNS hostname of the instance. See [DNS Hostnames](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html#vpc-dns-hostnames) and [To change the system hostname without a public DNS name](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/set-hostname.html#set-hostname-system) for more details. -- Label the EC2 instances with the key `KubernetesCluster` and assign the same value across all nodes. +- Label the EC2 instances with the key `KubernetesCluster` and assign the same value across all nodes, for example, `UCPKubenertesCluster`. ### Cluster Configuration From 2cc5b2df34757f188a9bcaf87db71df64f38196b Mon Sep 17 00:00:00 2001 From: paigehargrave Date: Wed, 13 Feb 2019 17:24:07 -0500 Subject: [PATCH 20/23] Update plan-installation.md --- datacenter/ucp/3.0/guides/admin/install/plan-installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datacenter/ucp/3.0/guides/admin/install/plan-installation.md b/datacenter/ucp/3.0/guides/admin/install/plan-installation.md index 0ca443f90a..98e56c29df 100644 --- a/datacenter/ucp/3.0/guides/admin/install/plan-installation.md +++ b/datacenter/ucp/3.0/guides/admin/install/plan-installation.md @@ -42,7 +42,7 @@ this. ## Avoid IP range conflicts -The `service-cluster-ip-range` API Server flag is currently set to `10.96.0.0/16` and cannot be changed. +The `service-cluster-ip-range` Kubernetes API Server flag is currently set to `10.96.0.0/16` and cannot be changed. ## Time synchronization From 8ef78aade4df0b2c4575add3b3ea2cf4852533b0 Mon Sep 17 00:00:00 2001 From: paigehargrave Date: Wed, 13 Feb 2019 17:24:38 -0500 Subject: [PATCH 21/23] Update plan-installation.md --- ee/ucp/admin/install/plan-installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ee/ucp/admin/install/plan-installation.md b/ee/ucp/admin/install/plan-installation.md index 27195a9b05..95cb1db9ec 100644 --- a/ee/ucp/admin/install/plan-installation.md +++ b/ee/ucp/admin/install/plan-installation.md @@ -42,7 +42,7 @@ this. ## Avoid IP range conflicts -The `service-cluster-ip-range` API Server flag is currently set to `10.96.0.0/16` and cannot be changed. +The `service-cluster-ip-range` Kubernetes API Server flag is currently set to `10.96.0.0/16` and cannot be changed. Swarm uses a default address pool of `10.0.0.0/16` for its overlay networks. If this conflicts with your current network implementation, please use a custom IP address pool. To specify a custom IP address pool, use the `--default-address-pool` command line option during [Swarm initialization](../../../../engine/swarm/swarm-mode.md). From dba1f18ebe1b803c47d83d9e2dca8a1a88bbe05b Mon Sep 17 00:00:00 2001 From: Maria Bermudez Date: Wed, 13 Feb 2019 16:07:51 -0800 Subject: [PATCH 22/23] Addresses 8242 --- ee/ucp/admin/configure/use-nfs-volumes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ee/ucp/admin/configure/use-nfs-volumes.md b/ee/ucp/admin/configure/use-nfs-volumes.md index b4d9fadb49..c53490a1ab 100644 --- a/ee/ucp/admin/configure/use-nfs-volumes.md +++ b/ee/ucp/admin/configure/use-nfs-volumes.md @@ -9,8 +9,8 @@ Kubernetes. To enable this feature on a UCP cluster, you need to set up an NFS storage volume provisioner. > Kubernetes storage drivers -> -> Currently, NFS is the only Kubernetes storage driver that UCP supports. + +>NFS is one of the Kubernetes storage drivers that UCP supports. See [Kubernetes Volume Drivers](https://success.docker.com/article/compatibility-matrix#kubernetesvolumedrivers) in the Compatibility Matrix for the full list. {: important} ## Enable NFS volume provisioning From d1cf7a861693515123b422aa0e814517b850af23 Mon Sep 17 00:00:00 2001 From: Maria Bermudez Date: Wed, 13 Feb 2019 16:21:42 -0800 Subject: [PATCH 23/23] Fix note formatting --- ee/ucp/admin/configure/use-nfs-volumes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ee/ucp/admin/configure/use-nfs-volumes.md b/ee/ucp/admin/configure/use-nfs-volumes.md index c53490a1ab..821a94c827 100644 --- a/ee/ucp/admin/configure/use-nfs-volumes.md +++ b/ee/ucp/admin/configure/use-nfs-volumes.md @@ -8,8 +8,8 @@ Docker UCP supports Network File System (NFS) persistent volumes for Kubernetes. To enable this feature on a UCP cluster, you need to set up an NFS storage volume provisioner. -> Kubernetes storage drivers - +> ### Kubernetes storage drivers +> >NFS is one of the Kubernetes storage drivers that UCP supports. See [Kubernetes Volume Drivers](https://success.docker.com/article/compatibility-matrix#kubernetesvolumedrivers) in the Compatibility Matrix for the full list. {: important}