Compare commits
13 Commits
snyk-fix-2
...
fix/EE-187
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
372a0c81e6 | ||
|
|
e22c4411e0 | ||
|
|
158cdf596a | ||
|
|
3d6c6e2604 | ||
|
|
1ee363f8c9 | ||
|
|
109b27594a | ||
|
|
54d47ebc76 | ||
|
|
e6d690e31e | ||
|
|
6a67e8142d | ||
|
|
d93d88fead | ||
|
|
685552a661 | ||
|
|
1b0e58a4e8 | ||
|
|
151dfe7e65 |
@@ -93,7 +93,7 @@ func (manager *ComposeStackManager) fetchEndpointProxy(endpoint *portainer.Endpo
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
return fmt.Sprintf("http://127.0.0.1:%d", proxy.Port), proxy, nil
|
||||
return fmt.Sprintf("tcp://127.0.0.1:%d", proxy.Port), proxy, nil
|
||||
}
|
||||
|
||||
func createEnvFile(stack *portainer.Stack) (string, error) {
|
||||
|
||||
40
api/go.mod
40
api/go.mod
@@ -3,37 +3,31 @@ module github.com/portainer/portainer/api
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Microsoft/go-winio v0.4.16
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
|
||||
github.com/Microsoft/go-winio v0.4.17
|
||||
github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535
|
||||
github.com/boltdb/bolt v1.3.1
|
||||
github.com/containerd/containerd v1.3.1 // indirect
|
||||
github.com/containerd/containerd v1.5.7 // indirect
|
||||
github.com/coreos/go-semver v0.3.0
|
||||
github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/docker/cli v0.0.0-20191126203649-54d085b857e9
|
||||
github.com/docker/distribution v2.7.1+incompatible // indirect
|
||||
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0
|
||||
github.com/docker/cli v20.10.9+incompatible
|
||||
github.com/docker/docker v20.10.9+incompatible
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-units v0.4.0 // indirect
|
||||
github.com/g07cha/defender v0.0.0-20180505193036-5665c627c814
|
||||
github.com/go-git/go-git/v5 v5.3.0
|
||||
github.com/go-ldap/ldap/v3 v3.1.8
|
||||
github.com/gofrs/uuid v3.2.0+incompatible
|
||||
github.com/gofrs/uuid v4.0.0+incompatible
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/gorilla/mux v1.7.3
|
||||
github.com/gorilla/securecookie v1.1.1
|
||||
github.com/gorilla/websocket v1.4.1
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/joho/godotenv v1.3.0
|
||||
github.com/jpillora/chisel v0.0.0-20190724232113-f3a8df20e389
|
||||
github.com/json-iterator/go v1.1.10
|
||||
github.com/json-iterator/go v1.1.11
|
||||
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c
|
||||
github.com/mattn/go-shellwords v1.0.6 // indirect
|
||||
github.com/mitchellh/mapstructure v1.1.2 // indirect
|
||||
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.1 // indirect
|
||||
github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/portainer/docker-compose-wrapper v0.0.0-20210909083948-8be0d98451a1
|
||||
@@ -43,18 +37,14 @@ require (
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/swaggo/swag v1.7.3
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||
gotest.tools v2.2.0+incompatible // indirect
|
||||
k8s.io/api v0.17.2
|
||||
k8s.io/apimachinery v0.17.2
|
||||
k8s.io/client-go v0.17.2
|
||||
k8s.io/api v0.22.2
|
||||
k8s.io/apimachinery v0.22.2
|
||||
k8s.io/client-go v0.22.2
|
||||
)
|
||||
|
||||
replace github.com/docker/docker => github.com/docker/engine v1.4.2-0.20200204220554-5f6d6f3f2203
|
||||
|
||||
replace golang.org/x/sys => golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456
|
||||
|
||||
965
api/go.sum
965
api/go.sum
File diff suppressed because it is too large
Load Diff
@@ -39,6 +39,7 @@ func (payload *authenticatePayload) Validate(r *http.Request) error {
|
||||
|
||||
// @id AuthenticateUser
|
||||
// @summary Authenticate
|
||||
// @description **Access policy**: public
|
||||
// @description Use this environment(endpoint) to authenticate against Portainer using a username and password.
|
||||
// @tags auth
|
||||
// @accept json
|
||||
|
||||
@@ -44,6 +44,7 @@ func (handler *Handler) authenticateOAuth(code string, settings *portainer.OAuth
|
||||
|
||||
// @id ValidateOAuth
|
||||
// @summary Authenticate with OAuth
|
||||
// @description **Access policy**: public
|
||||
// @tags auth
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
// @id Logout
|
||||
// @summary Logout
|
||||
// @description **Access policy**: authenticated
|
||||
// @security jwt
|
||||
// @tags auth
|
||||
// @success 204 "Success"
|
||||
|
||||
@@ -27,8 +27,9 @@ func (p *backupPayload) Validate(r *http.Request) error {
|
||||
// @description **Access policy**: admin
|
||||
// @tags backup
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce octet-stream
|
||||
// @param Password body string false "Password to encrypt the backup with"
|
||||
// @param body body backupPayload false "An object contains the password to encrypt the backup with"
|
||||
// @success 200 "Success"
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 500 "Server error"
|
||||
|
||||
@@ -22,10 +22,9 @@ type restorePayload struct {
|
||||
// @description Triggers a system restore using provided backup file
|
||||
// @description **Access policy**: public
|
||||
// @tags backup
|
||||
// @param FileContent body []byte true "Content of the backup"
|
||||
// @param FileName body string true "File name"
|
||||
// @param Password body string false "Password to decrypt the backup with"
|
||||
// @success 200 "Success"
|
||||
// @accept json
|
||||
// @param restorePayload body restorePayload true "Restore request payload"
|
||||
// @success 200 "Success"
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 500 "Server error"
|
||||
// @router /restore [post]
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
// @id CustomTemplateDelete
|
||||
// @summary Remove a template
|
||||
// @description Remove a template.
|
||||
// @description **Access policy**: authorized
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags custom_templates
|
||||
// @security jwt
|
||||
// @param id path int true "Template identifier"
|
||||
|
||||
@@ -18,7 +18,7 @@ type fileResponse struct {
|
||||
// @id CustomTemplateFile
|
||||
// @summary Get Template stack file content.
|
||||
// @description Retrieve the content of the Stack file for the specified custom template
|
||||
// @description **Access policy**: authorized
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags custom_templates
|
||||
// @security jwt
|
||||
// @produce json
|
||||
|
||||
@@ -19,7 +19,6 @@ import (
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags custom_templates
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path int true "Template identifier"
|
||||
// @success 200 {object} portainer.CustomTemplate "Success"
|
||||
|
||||
@@ -34,7 +34,7 @@ func (payload *edgeGroupCreatePayload) Validate(r *http.Request) error {
|
||||
|
||||
// @id EdgeGroupCreate
|
||||
// @summary Create an EdgeGroup
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_groups
|
||||
// @security jwt
|
||||
// @accept json
|
||||
|
||||
@@ -13,11 +13,9 @@ import (
|
||||
|
||||
// @id EdgeGroupDelete
|
||||
// @summary Deletes an EdgeGroup
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_groups
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path int true "EdgeGroup Id"
|
||||
// @success 204
|
||||
// @failure 503 "Edge compute features are disabled"
|
||||
|
||||
@@ -12,10 +12,9 @@ import (
|
||||
|
||||
// @id EdgeGroupInspect
|
||||
// @summary Inspects an EdgeGroup
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_groups
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path int true "EdgeGroup Id"
|
||||
// @success 200 {object} portainer.EdgeGroup
|
||||
|
||||
@@ -17,10 +17,9 @@ type decoratedEdgeGroup struct {
|
||||
|
||||
// @id EdgeGroupList
|
||||
// @summary list EdgeGroups
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_groups
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @success 200 {array} portainer.EdgeGroup{HasEdgeStack=bool} "EdgeGroups"
|
||||
// @failure 500
|
||||
|
||||
@@ -36,7 +36,7 @@ func (payload *edgeGroupUpdatePayload) Validate(r *http.Request) error {
|
||||
|
||||
// @id EgeGroupUpdate
|
||||
// @summary Updates an EdgeGroup
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_groups
|
||||
// @security jwt
|
||||
// @accept json
|
||||
|
||||
@@ -16,10 +16,9 @@ import (
|
||||
|
||||
// @id EdgeJobCreate
|
||||
// @summary Create an EdgeJob
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param method query string true "Creation Method" Enums(file, string)
|
||||
// @param body_string body edgeJobCreateFromFileContentPayload true "EdgeGroup data when method is string"
|
||||
|
||||
@@ -13,11 +13,9 @@ import (
|
||||
|
||||
// @id EdgeJobDelete
|
||||
// @summary Delete an EdgeJob
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path string true "EdgeJob Id"
|
||||
// @success 204
|
||||
// @failure 500
|
||||
|
||||
@@ -16,10 +16,9 @@ type edgeJobFileResponse struct {
|
||||
|
||||
// @id EdgeJobFile
|
||||
// @summary Fetch a file of an EdgeJob
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path string true "EdgeJob Id"
|
||||
// @success 200 {object} edgeJobFileResponse
|
||||
|
||||
@@ -17,10 +17,9 @@ type edgeJobInspectResponse struct {
|
||||
|
||||
// @id EdgeJobInspect
|
||||
// @summary Inspect an EdgeJob
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path string true "EdgeJob Id"
|
||||
// @success 200 {object} portainer.EdgeJob
|
||||
|
||||
@@ -9,10 +9,9 @@ import (
|
||||
|
||||
// @id EdgeJobList
|
||||
// @summary Fetch EdgeJobs list
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @success 200 {array} portainer.EdgeJob
|
||||
// @failure 500
|
||||
|
||||
@@ -13,10 +13,9 @@ import (
|
||||
|
||||
// @id EdgeJobTasksClear
|
||||
// @summary Clear the log for a specifc task on an EdgeJob
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path string true "EdgeJob Id"
|
||||
// @param taskID path string true "Task Id"
|
||||
|
||||
@@ -12,10 +12,9 @@ import (
|
||||
|
||||
// @id EdgeJobTasksCollect
|
||||
// @summary Collect the log for a specifc task on an EdgeJob
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path string true "EdgeJob Id"
|
||||
// @param taskID path string true "Task Id"
|
||||
|
||||
@@ -15,10 +15,9 @@ type fileResponse struct {
|
||||
|
||||
// @id EdgeJobTaskLogsInspect
|
||||
// @summary Fetch the log for a specifc task on an EdgeJob
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path string true "EdgeJob Id"
|
||||
// @param taskID path string true "Task Id"
|
||||
|
||||
@@ -19,10 +19,9 @@ type taskContainer struct {
|
||||
|
||||
// @id EdgeJobTasksList
|
||||
// @summary Fetch the list of tasks on an EdgeJob
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path string true "EdgeJob Id"
|
||||
// @success 200 {array} taskContainer
|
||||
|
||||
@@ -30,7 +30,7 @@ func (payload *edgeJobUpdatePayload) Validate(r *http.Request) error {
|
||||
|
||||
// @id EdgeJobUpdate
|
||||
// @summary Update an EdgeJob
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security jwt
|
||||
// @accept json
|
||||
|
||||
@@ -19,10 +19,9 @@ import (
|
||||
|
||||
// @id EdgeStackCreate
|
||||
// @summary Create an EdgeStack
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_stacks
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param method query string true "Creation Method" Enums(file,string,repository)
|
||||
// @param body_string body swarmStackFromFileContentPayload true "Required when using method=string"
|
||||
|
||||
@@ -13,11 +13,9 @@ import (
|
||||
|
||||
// @id EdgeStackDelete
|
||||
// @summary Delete an EdgeStack
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_stacks
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path string true "EdgeStack Id"
|
||||
// @success 204
|
||||
// @failure 500
|
||||
|
||||
@@ -17,10 +17,9 @@ type stackFileResponse struct {
|
||||
|
||||
// @id EdgeStackFile
|
||||
// @summary Fetches the stack file for an EdgeStack
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_stacks
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path string true "EdgeStack Id"
|
||||
// @success 200 {object} stackFileResponse
|
||||
|
||||
@@ -12,10 +12,9 @@ import (
|
||||
|
||||
// @id EdgeStackInspect
|
||||
// @summary Inspect an EdgeStack
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_stacks
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path string true "EdgeStack Id"
|
||||
// @success 200 {object} portainer.EdgeStack
|
||||
|
||||
@@ -9,10 +9,9 @@ import (
|
||||
|
||||
// @id EdgeStackList
|
||||
// @summary Fetches the list of EdgeStacks
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_stacks
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @success 200 {array} portainer.EdgeStack
|
||||
// @failure 500
|
||||
|
||||
@@ -33,7 +33,7 @@ func (payload *updateEdgeStackPayload) Validate(r *http.Request) error {
|
||||
|
||||
// @id EdgeStackUpdate
|
||||
// @summary Update an EdgeStack
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_stacks
|
||||
// @security jwt
|
||||
// @accept json
|
||||
|
||||
@@ -17,7 +17,7 @@ type templateFileFormat struct {
|
||||
|
||||
// @id EdgeTemplateList
|
||||
// @summary Fetches the list of Edge Templates
|
||||
// @description
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_templates
|
||||
// @security jwt
|
||||
// @accept json
|
||||
|
||||
@@ -21,7 +21,7 @@ func (payload *logsPayload) Validate(r *http.Request) error {
|
||||
|
||||
// endpointEdgeJobsLogs
|
||||
// @summary Inspect an EdgeJob Log
|
||||
// @description
|
||||
// @description **Access policy**: public
|
||||
// @tags edge, endpoints
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
||||
@@ -19,7 +19,7 @@ type configResponse struct {
|
||||
}
|
||||
|
||||
// @summary Inspect an Edge Stack for an Environment(Endpoint)
|
||||
// @description
|
||||
// @description **Access policy**: public
|
||||
// @tags edge, endpoints, edge_stacks
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
||||
@@ -17,8 +17,6 @@ import (
|
||||
// @description **Access policy**: administrator
|
||||
// @tags endpoint_groups
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path int true "EndpointGroup identifier"
|
||||
// @success 204 "Success"
|
||||
// @failure 400 "Invalid request"
|
||||
|
||||
@@ -27,7 +27,7 @@ import (
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 404 "Environment(Endpoint) not found"
|
||||
// @failure 500 "Server error"
|
||||
// @router /api/endpoints/{id}/association [put]
|
||||
// @router /endpoints/{id}/association [put]
|
||||
func (handler *Handler) endpointAssociationDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id")
|
||||
if err != nil {
|
||||
|
||||
@@ -18,11 +18,27 @@ import (
|
||||
)
|
||||
|
||||
type dockerhubStatusResponse struct {
|
||||
// Remaiming images to pull
|
||||
Remaining int `json:"remaining"`
|
||||
Limit int `json:"limit"`
|
||||
// Daily limit
|
||||
Limit int `json:"limit"`
|
||||
}
|
||||
|
||||
// GET request on /api/endpoints/{id}/dockerhub/{registryId}
|
||||
// @id endpointDockerhubStatus
|
||||
// @summary fetch docker pull limits
|
||||
// @description get docker pull limits for a docker hub registry in the environment
|
||||
// @description **Access policy**:
|
||||
// @tags endpoints
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "endpoint ID"
|
||||
// @param registryId path int true "registry ID"
|
||||
// @success 200 {object} dockerhubStatusResponse "Success"
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 403 "Permission denied"
|
||||
// @failure 404 "registry or endpoint not found"
|
||||
// @failure 500 "Server error"
|
||||
// @router /endpoints/{id}/dockerhub/{registryId} [get]
|
||||
func (handler *Handler) endpointDockerhubStatus(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id")
|
||||
if err != nil {
|
||||
|
||||
@@ -29,6 +29,12 @@ func (payload *endpointExtensionAddPayload) Validate(r *http.Request) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// @id endpointExtensionAdd
|
||||
// @tags endpoints
|
||||
// @deprecated
|
||||
// @param id path int true "Environment(Endpoint) identifier"
|
||||
// @success 204 "Success"
|
||||
// @router /endpoints/{id}/extensions [post]
|
||||
func (handler *Handler) endpointExtensionAdd(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id")
|
||||
if err != nil {
|
||||
|
||||
@@ -12,6 +12,13 @@ import (
|
||||
"github.com/portainer/portainer/api/bolt/errors"
|
||||
)
|
||||
|
||||
// @id endpointExtensionRemove
|
||||
// @tags endpoints
|
||||
// @deprecated
|
||||
// @param id path int true "Environment(Endpoint) identifier"
|
||||
// @param extensionType path string true "Extension Type"
|
||||
// @success 204 "Success"
|
||||
// @router /endpoints/{id}/extensions/{extensionType} [delete]
|
||||
func (handler *Handler) endpointExtensionRemove(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id")
|
||||
if err != nil {
|
||||
|
||||
@@ -12,7 +12,20 @@ import (
|
||||
"github.com/portainer/portainer/api/http/security"
|
||||
)
|
||||
|
||||
// GET request on /endpoints/{id}/registries/{registryId}
|
||||
// @id endpointRegistryInspect
|
||||
// @summary get registry for environment
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags endpoints
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "identifier"
|
||||
// @param registryId path int true "Registry identifier"
|
||||
// @success 200 {object} portainer.Registry "Success"
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 403 "Permission denied"
|
||||
// @failure 404 "Registry not found"
|
||||
// @failure 500 "Server error"
|
||||
// @router /endpoints/{id}/registries/{registryId} [get]
|
||||
func (handler *Handler) endpointRegistryInspect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id")
|
||||
if err != nil {
|
||||
|
||||
@@ -13,7 +13,18 @@ import (
|
||||
"github.com/portainer/portainer/api/internal/endpointutils"
|
||||
)
|
||||
|
||||
// GET request on /endpoints/{id}/registries?namespace
|
||||
// @id endpointRegistriesList
|
||||
// @summary List Registries on environment
|
||||
// @description List all registries based on the current user authorizations in current environment.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags endpoints
|
||||
// @param namespace query string false "required if kubernetes environment, will show registries by namespace"
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "Environment(Endpoint) identifier"
|
||||
// @success 200 {array} portainer.Registry "Success"
|
||||
// @failure 500 "Server error"
|
||||
// @router /endpoints/{id}/registries [get]
|
||||
func (handler *Handler) endpointRegistriesList(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
securityContext, err := security.RetrieveRestrictedRequestContext(r)
|
||||
if err != nil {
|
||||
|
||||
@@ -21,7 +21,22 @@ func (payload *registryAccessPayload) Validate(r *http.Request) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// PUT request on /endpoints/{id}/registries/{registryId}
|
||||
// @id endpointRegistryAccess
|
||||
// @summary update registry access for environment
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags endpoints
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path int true "Environment(Endpoint) identifier"
|
||||
// @param registryId path int true "Registry identifier"
|
||||
// @param body body registryAccessPayload true "details"
|
||||
// @success 204 "Success"
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 403 "Permission denied"
|
||||
// @failure 404 "Endpoint not found"
|
||||
// @failure 500 "Server error"
|
||||
// @router /endpoints/{id}/registries/{registryId} [put]
|
||||
func (handler *Handler) endpointRegistryAccess(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id")
|
||||
if err != nil {
|
||||
|
||||
@@ -36,9 +36,9 @@ func (payload *endpointSettingsUpdatePayload) Validate(r *http.Request) error {
|
||||
}
|
||||
|
||||
// @id EndpointSettingsUpdate
|
||||
// @summary Update settings for an environments(endpoints)
|
||||
// @description Update settings for an environments(endpoints).
|
||||
// @description **Access policy**: administrator
|
||||
// @summary Update settings for an environment(endpoint)
|
||||
// @description Update settings for an environment(endpoint).
|
||||
// @description **Access policy**: authenticated
|
||||
// @security jwt
|
||||
// @tags endpoints
|
||||
// @accept json
|
||||
@@ -49,7 +49,7 @@ func (payload *endpointSettingsUpdatePayload) Validate(r *http.Request) error {
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 404 "Environment(Endpoint) not found"
|
||||
// @failure 500 "Server error"
|
||||
// @router /api/endpoints/{id}/settings [put]
|
||||
// @router /endpoints/{id}/settings [put]
|
||||
func (handler *Handler) endpointSettingsUpdate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id")
|
||||
if err != nil {
|
||||
|
||||
@@ -12,9 +12,9 @@ import (
|
||||
)
|
||||
|
||||
// @id EndpointSnapshot
|
||||
// @summary Snapshots an environments(endpoints)
|
||||
// @description Snapshots an environments(endpoints)
|
||||
// @description **Access policy**: restricted
|
||||
// @summary Snapshots an environment(endpoint)
|
||||
// @description Snapshots an environment(endpoint)
|
||||
// @description **Access policy**: administrator
|
||||
// @tags endpoints
|
||||
// @security jwt
|
||||
// @param id path int true "Environment(Endpoint) identifier"
|
||||
|
||||
@@ -56,7 +56,7 @@ func (payload *endpointUpdatePayload) Validate(r *http.Request) error {
|
||||
// @id EndpointUpdate
|
||||
// @summary Update an environment(endpoint)
|
||||
// @description Update an environment(endpoint).
|
||||
// @description **Access policy**: administrator
|
||||
// @description **Access policy**: authenticated
|
||||
// @security jwt
|
||||
// @tags endpoints
|
||||
// @accept json
|
||||
|
||||
@@ -12,11 +12,9 @@ import (
|
||||
// @id HelmDelete
|
||||
// @summary Delete Helm Release
|
||||
// @description
|
||||
// @description **Access policy**: authorized
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags helm
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path int true "Environment(Endpoint) identifier"
|
||||
// @param release path string true "The name of the release/application to uninstall"
|
||||
// @param namespace query string true "An optional namespace"
|
||||
|
||||
@@ -36,7 +36,7 @@ var errChartNameInvalid = errors.New("invalid chart name. " +
|
||||
// @id HelmInstall
|
||||
// @summary Install Helm Chart
|
||||
// @description
|
||||
// @description **Access policy**: authorized
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags helm
|
||||
// @security jwt
|
||||
// @accept json
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
// @id HelmList
|
||||
// @summary List Helm Releases
|
||||
// @description
|
||||
// @description **Access policy**: authorized
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags helm
|
||||
// @security jwt
|
||||
// @accept json
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
// @id HelmRepoSearch
|
||||
// @summary Search Helm Charts
|
||||
// @description
|
||||
// @description **Access policy**: authorized
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags helm
|
||||
// @param repo query string true "Helm repository URL"
|
||||
// @security jwt
|
||||
|
||||
@@ -15,8 +15,8 @@ import (
|
||||
// @id HelmShow
|
||||
// @summary Show Helm Chart Information
|
||||
// @description
|
||||
// @description **Access policy**: authorized
|
||||
// @tags helm_chart
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags helm
|
||||
// @param repo query string true "Helm repository URL"
|
||||
// @param chart query string true "Chart name"
|
||||
// @param command path string true "chart/values/readme"
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
// @id GetKubernetesConfig
|
||||
// @summary Generates kubeconfig file enabling client communication with k8s api server
|
||||
// @description Generates kubeconfig file enabling client communication with k8s api server
|
||||
// @description **Access policy**: authorized
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags kubernetes
|
||||
// @security jwt
|
||||
// @accept json
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
// @id getKubernetesNodesLimits
|
||||
// @summary Get CPU and memory limits of all nodes within k8s cluster
|
||||
// @description Get CPU and memory limits of all nodes within k8s cluster
|
||||
// @description **Access policy**: authorized
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags kubernetes
|
||||
// @security jwt
|
||||
// @accept json
|
||||
|
||||
@@ -26,7 +26,9 @@ type motdData struct {
|
||||
Style string `json:"style"`
|
||||
}
|
||||
|
||||
// @id MOTD
|
||||
// @summary fetches the message of the day
|
||||
// @description **Access policy**: restricted
|
||||
// @tags motd
|
||||
// @security jwt
|
||||
// @produce json
|
||||
|
||||
@@ -81,7 +81,7 @@ func (payload *registryConfigurePayload) Validate(r *http.Request) error {
|
||||
// @id RegistryConfigure
|
||||
// @summary Configures a registry
|
||||
// @description Configures a registry.
|
||||
// @description **Access policy**: admin
|
||||
// @description **Access policy**: restricted
|
||||
// @tags registries
|
||||
// @security jwt
|
||||
// @accept json
|
||||
|
||||
@@ -62,7 +62,7 @@ func (payload *registryCreatePayload) Validate(_ *http.Request) error {
|
||||
// @id RegistryCreate
|
||||
// @summary Create a new registry
|
||||
// @description Create a new registry.
|
||||
// @description **Access policy**: administrator
|
||||
// @description **Access policy**: restricted
|
||||
// @tags registries
|
||||
// @security jwt
|
||||
// @accept json
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
// @id RegistryDelete
|
||||
// @summary Remove a registry
|
||||
// @description Remove a registry
|
||||
// @description **Access policy**: administrator
|
||||
// @description **Access policy**: restricted
|
||||
// @tags registries
|
||||
// @security jwt
|
||||
// @param id path int true "Registry identifier"
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
// @id RegistryInspect
|
||||
// @summary Inspect a registry
|
||||
// @description Retrieve details about a registry.
|
||||
// @description **Access policy**: administrator
|
||||
// @description **Access policy**: restricted
|
||||
// @tags registries
|
||||
// @security jwt
|
||||
// @produce json
|
||||
|
||||
@@ -37,7 +37,7 @@ func (payload *registryUpdatePayload) Validate(r *http.Request) error {
|
||||
// @id RegistryUpdate
|
||||
// @summary Update a registry
|
||||
// @description Update a registry
|
||||
// @description **Access policy**: administrator
|
||||
// @description **Access policy**: restricted
|
||||
// @tags registries
|
||||
// @security jwt
|
||||
// @accept json
|
||||
|
||||
@@ -38,7 +38,7 @@ func (payload *resourceControlUpdatePayload) Validate(r *http.Request) error {
|
||||
// @id ResourceControlUpdate
|
||||
// @summary Update a resource control
|
||||
// @description Update a resource control
|
||||
// @description **Access policy**: restricted
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags resource_controls
|
||||
// @security jwt
|
||||
// @accept json
|
||||
|
||||
@@ -14,7 +14,22 @@ import (
|
||||
"github.com/portainer/portainer/api/internal/stackutils"
|
||||
)
|
||||
|
||||
// PUT request on /api/stacks/:id/associate?endpointId=<endpointId>&swarmId=<swarmId>&orphanedRunning=<orphanedRunning>
|
||||
// @id StackAssociate
|
||||
// @summary Associate an orphaned stack to a new environment(endpoint)
|
||||
// @description **Access policy**: administrator
|
||||
// @tags stacks
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "Stack identifier"
|
||||
// @param endpointId query int true "Stacks created before version 1.18.0 might not have an associated environment(endpoint) identifier. Use this optional parameter to set the environment(endpoint) identifier used by the stack."
|
||||
// @param swarmId query int true "Swarm identifier"
|
||||
// @param orphanedRunning query boolean true "Indicates whether the stack is orphaned"
|
||||
// @success 200 {object} portainer.Stack "Success"
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 403 "Permission denied"
|
||||
// @failure 404 "Stack not found"
|
||||
// @failure 500 "Server error"
|
||||
// @router /stacks/{id}/associate [put]
|
||||
func (handler *Handler) stackAssociate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
stackID, err := request.RetrieveNumericRouteVariableValue(r, "id")
|
||||
if err != nil {
|
||||
|
||||
@@ -33,7 +33,7 @@ func (handler *Handler) cleanUp(stack *portainer.Stack, doCleanUp *bool) error {
|
||||
// @id StackCreate
|
||||
// @summary Deploy a new stack
|
||||
// @description Deploy a new stack into a Docker environment(endpoint) specified via the environment(endpoint) identifier.
|
||||
// @description **Access policy**: restricted
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security jwt
|
||||
// @accept json,multipart/form-data
|
||||
|
||||
@@ -24,7 +24,7 @@ type stackListOperationFilters struct {
|
||||
// @description List all stacks based on the current user authorizations.
|
||||
// @description Will return all stacks if using an administrator account otherwise it
|
||||
// @description will only return the list of stacks the user have access to.
|
||||
// @description **Access policy**: restricted
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security jwt
|
||||
// @param filters query string false "Filters to process on the stack list. Encoded as JSON (a map[string]string). For example, {"SwarmID": "jpofkc0i9uo9wtx1zesuk649w"} will only return stacks that are part of the specified Swarm cluster. Available filters: EndpointID, SwarmID."
|
||||
|
||||
@@ -34,7 +34,7 @@ func (payload *stackMigratePayload) Validate(r *http.Request) error {
|
||||
// @id StackMigrate
|
||||
// @summary Migrate a stack to another environment(endpoint)
|
||||
// @description Migrate a stack from an environment(endpoint) to another environment(endpoint). It will re-create the stack inside the target environment(endpoint) before removing the original stack.
|
||||
// @description **Access policy**: restricted
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security jwt
|
||||
// @produce json
|
||||
@@ -143,12 +143,14 @@ func (handler *Handler) stackMigrate(w http.ResponseWriter, r *http.Request) *ht
|
||||
return migrationError
|
||||
}
|
||||
|
||||
newName := stack.Name
|
||||
stack.Name = oldName
|
||||
err = handler.deleteStack(securityContext.UserID, stack, endpoint)
|
||||
if err != nil {
|
||||
return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: err.Error(), Err: err}
|
||||
}
|
||||
|
||||
stack.Name = newName
|
||||
err = handler.DataStore.Stack().UpdateStack(stack.ID, stack)
|
||||
if err != nil {
|
||||
return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to persist the stack changes inside the database", Err: err}
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
// @id StackStart
|
||||
// @summary Starts a stopped Stack
|
||||
// @description Starts a stopped Stack.
|
||||
// @description **Access policy**: restricted
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security jwt
|
||||
// @param id path int true "Stack identifier"
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
// @id StackStop
|
||||
// @summary Stops a stopped Stack
|
||||
// @description Stops a stopped Stack.
|
||||
// @description **Access policy**: restricted
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security jwt
|
||||
// @param id path int true "Stack identifier"
|
||||
|
||||
@@ -51,7 +51,7 @@ func (payload *updateSwarmStackPayload) Validate(r *http.Request) error {
|
||||
// @id StackUpdate
|
||||
// @summary Update a stack
|
||||
// @description Update a stack.
|
||||
// @description **Access policy**: restricted
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security jwt
|
||||
// @accept json
|
||||
|
||||
@@ -40,7 +40,7 @@ func (payload *stackGitUpdatePayload) Validate(r *http.Request) error {
|
||||
// @id StackUpdateGit
|
||||
// @summary Update a stack's Git configs
|
||||
// @description Update the Git settings in a stack, e.g., RepositoryReferenceName and AutoUpdate
|
||||
// @description **Access policy**: restricted
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security jwt
|
||||
// @accept json
|
||||
|
||||
@@ -38,7 +38,7 @@ func (payload *stackGitRedployPayload) Validate(r *http.Request) error {
|
||||
// @id StackGitRedeploy
|
||||
// @summary Redeploy a stack
|
||||
// @description Pull and redeploy a stack via Git
|
||||
// @description **Access policy**: restricted
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security jwt
|
||||
// @accept json
|
||||
|
||||
@@ -15,6 +15,16 @@ import (
|
||||
"github.com/portainer/libhttp/request"
|
||||
)
|
||||
|
||||
// @id WebhookInvoke
|
||||
// @summary Webhook for triggering stack updates from git
|
||||
// @description **Access policy**: public
|
||||
// @tags stacks
|
||||
// @param webhookID path string true "Stack identifier"
|
||||
// @success 200 "Success"
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 409 "Conflict"
|
||||
// @failure 500 "Server error"
|
||||
// @router /stacks/webhooks/{webhookID} [post]
|
||||
func (handler *Handler) webhookInvoke(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
webhookID, err := retrieveUUIDRouteVariableValue(r, "webhookID")
|
||||
if err != nil {
|
||||
|
||||
@@ -29,6 +29,7 @@ func (payload *tagCreatePayload) Validate(r *http.Request) error {
|
||||
// @description **Access policy**: administrator
|
||||
// @tags tags
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param body body tagCreatePayload true "Tag details"
|
||||
// @success 200 {object} portainer.Tag "Success"
|
||||
|
||||
@@ -17,8 +17,6 @@ import (
|
||||
// @description **Access policy**: administrator
|
||||
// @tags tags
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path int true "Tag identifier"
|
||||
// @success 204 "Success"
|
||||
// @failure 400 "Invalid request"
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
// @id TagList
|
||||
// @summary List tags
|
||||
// @description List tags.
|
||||
// @description **Access policy**: administrator
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags tags
|
||||
// @security jwt
|
||||
// @produce json
|
||||
|
||||
@@ -37,7 +37,7 @@ func (payload *teamMembershipCreatePayload) Validate(r *http.Request) error {
|
||||
// @id TeamMembershipCreate
|
||||
// @summary Create a new team membership
|
||||
// @description Create a new team memberships. Access is only available to administrators leaders of the associated team.
|
||||
// @description **Access policy**: admin
|
||||
// @description **Access policy**: administrator
|
||||
// @tags team_memberships
|
||||
// @security jwt
|
||||
// @accept json
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
// @id TeamMembershipDelete
|
||||
// @summary Remove a team membership
|
||||
// @description Remove a team membership. Access is only available to administrators leaders of the associated team.
|
||||
// @description **Access policy**: restricted
|
||||
// @description **Access policy**: administrator
|
||||
// @tags team_memberships
|
||||
// @security jwt
|
||||
// @param id path int true "TeamMembership identifier"
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
// @id TeamMembershipList
|
||||
// @summary List team memberships
|
||||
// @description List team memberships. Access is only available to administrators and team leaders.
|
||||
// @description **Access policy**: admin
|
||||
// @description **Access policy**: administrator
|
||||
// @tags team_memberships
|
||||
// @security jwt
|
||||
// @produce json
|
||||
|
||||
@@ -38,7 +38,7 @@ func (payload *teamMembershipUpdatePayload) Validate(r *http.Request) error {
|
||||
// @id TeamMembershipUpdate
|
||||
// @summary Update a team membership
|
||||
// @description Update a team membership. Access is only available to administrators leaders of the associated team.
|
||||
// @description **Access policy**: restricted
|
||||
// @description **Access policy**: administrator
|
||||
// @tags team_memberships
|
||||
// @security jwt
|
||||
// @accept json
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
// @id TeamInspect
|
||||
// @summary Inspect a team
|
||||
// @description Retrieve details about a team. Access is only available for administrator and leaders of that team.
|
||||
// @description **Access policy**: restricted
|
||||
// @description **Access policy**: administrator
|
||||
// @tags teams
|
||||
// @security jwt
|
||||
// @produce json
|
||||
|
||||
@@ -23,7 +23,7 @@ func (payload *teamUpdatePayload) Validate(r *http.Request) error {
|
||||
// @summary Update a team
|
||||
// @description Update a team.
|
||||
// @description **Access policy**: administrator
|
||||
// @tags
|
||||
// @tags teams
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
|
||||
@@ -39,7 +39,7 @@ func (payload *filePayload) Validate(r *http.Request) error {
|
||||
// @id TemplateFile
|
||||
// @summary Get a template's file
|
||||
// @description Get a template's file
|
||||
// @description **Access policy**: restricted
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags templates
|
||||
// @security jwt
|
||||
// @accept json
|
||||
|
||||
@@ -17,7 +17,7 @@ type listResponse struct {
|
||||
// @id TemplateList
|
||||
// @summary List available templates
|
||||
// @description List available templates.
|
||||
// @description **Access policy**: restricted
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags templates
|
||||
// @security jwt
|
||||
// @produce json
|
||||
|
||||
@@ -32,7 +32,7 @@ func (payload *adminInitPayload) Validate(r *http.Request) error {
|
||||
// @summary Initialize administrator account
|
||||
// @description Initialize the 'admin' user account.
|
||||
// @description **Access policy**: public
|
||||
// @tags
|
||||
// @tags users
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param body body adminInitPayload true "User details"
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
// @description **Access policy**: administrator
|
||||
// @tags users
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path int true "User identifier"
|
||||
// @success 204 "Success"
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
// @summary Inspect a user
|
||||
// @description Retrieve details about a user.
|
||||
// @description User passwords are filtered out, and should never be accessible.
|
||||
// @description **Access policy**: administrator
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags users
|
||||
// @security jwt
|
||||
// @produce json
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
// @id UserMembershipsInspect
|
||||
// @summary Inspect a user memberships
|
||||
// @description Inspect a user memberships.
|
||||
// @description **Access policy**: authenticated
|
||||
// @description **Access policy**: restricted
|
||||
// @tags users
|
||||
// @security jwt
|
||||
// @produce json
|
||||
|
||||
@@ -33,7 +33,7 @@ func (payload *webhookCreatePayload) Validate(r *http.Request) error {
|
||||
}
|
||||
|
||||
// @summary Create a webhook
|
||||
// @description
|
||||
// @description **Access policy**: authenticated
|
||||
// @security jwt
|
||||
// @tags webhooks
|
||||
// @accept json
|
||||
|
||||
@@ -10,11 +10,9 @@ import (
|
||||
)
|
||||
|
||||
// @summary Delete a webhook
|
||||
// @description
|
||||
// @description **Access policy**: authenticated
|
||||
// @security jwt
|
||||
// @tags webhooks
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path int true "Webhook id"
|
||||
// @success 202 "Webhook deleted"
|
||||
// @failure 400
|
||||
|
||||
@@ -16,9 +16,8 @@ import (
|
||||
|
||||
// @summary Execute a webhook
|
||||
// @description Acts on a passed in token UUID to restart the docker service
|
||||
// @description **Access policy**: public
|
||||
// @tags webhooks
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param token path string true "Webhook token"
|
||||
// @success 202 "Webhook executed"
|
||||
// @failure 400
|
||||
|
||||
@@ -15,7 +15,7 @@ type webhookListOperationFilters struct {
|
||||
}
|
||||
|
||||
// @summary List webhooks
|
||||
// @description
|
||||
// @description **Access policy**: authenticated
|
||||
// @security jwt
|
||||
// @tags webhooks
|
||||
// @accept json
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
// @description If the nodeName query parameter is present, the request will be proxied to the underlying agent environment(endpoint).
|
||||
// @description If the nodeName query parameter is not specified, the request will be upgraded to the websocket protocol and
|
||||
// @description an AttachStart operation HTTP request will be created and hijacked.
|
||||
// @description Authentication and access is controlled via the mandatory token query parameter.
|
||||
// @description **Access policy**: authenticated
|
||||
// @security jwt
|
||||
// @tags websocket
|
||||
// @accept json
|
||||
|
||||
@@ -26,7 +26,7 @@ type execStartOperationPayload struct {
|
||||
// @description If the nodeName query parameter is present, the request will be proxied to the underlying agent environment(endpoint).
|
||||
// @description If the nodeName query parameter is not specified, the request will be upgraded to the websocket protocol and
|
||||
// @description an ExecStart operation HTTP request will be created and hijacked.
|
||||
// @description Authentication and access is controlled via the mandatory token query parameter.
|
||||
// @**Access policy**: authenticated
|
||||
// @security jwt
|
||||
// @tags websocket
|
||||
// @accept json
|
||||
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
|
||||
// @summary Execute a websocket on pod
|
||||
// @description The request will be upgraded to the websocket protocol.
|
||||
// @description Authentication and access is controlled via the mandatory token query parameter.
|
||||
// @description **Access policy**: authenticated
|
||||
// @security jwt
|
||||
// @tags websocket
|
||||
// @accept json
|
||||
|
||||
@@ -19,11 +19,10 @@ import (
|
||||
// @produce json
|
||||
// @param endpointId query int true "environment(endpoint) ID of the environment(endpoint) where the resource is located"
|
||||
// @param token query string true "JWT token used for authentication against this environment(endpoint)"
|
||||
// @success 200
|
||||
// @failure 400
|
||||
// @failure 403
|
||||
// @failure 404
|
||||
// @failure 500
|
||||
// @success 200 "Success"
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 403 "Permission denied"
|
||||
// @failure 500 "Server error"
|
||||
// @router /websocket/kubernetes-shell [get]
|
||||
func (handler *Handler) websocketShellPodExec(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
endpointID, err := request.RetrieveNumericQueryParameter(r, "endpointId", false)
|
||||
|
||||
@@ -46,5 +46,19 @@ func (transport *baseTransport) proxyNamespaceDeleteOperation(request *http.Requ
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stacks, err := transport.dataStore.Stack().Stacks()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, s := range stacks {
|
||||
if s.Namespace == namespace && s.EndpointID == transport.endpoint.ID {
|
||||
if err := transport.dataStore.Stack().DeleteStack(s.ID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return transport.executeKubernetesRequest(request)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@@ -27,7 +28,7 @@ func (kcl *KubeClient) NamespaceAccessPoliciesDeleteNamespace(ns string) error {
|
||||
// GetNamespaceAccessPolicies gets the namespace access policies
|
||||
// from config maps in the portainer namespace
|
||||
func (kcl *KubeClient) GetNamespaceAccessPolicies() (map[string]portainer.K8sNamespaceAccessPolicy, error) {
|
||||
configMap, err := kcl.cli.CoreV1().ConfigMaps(portainerNamespace).Get(portainerConfigMapName, metav1.GetOptions{})
|
||||
configMap, err := kcl.cli.CoreV1().ConfigMaps(portainerNamespace).Get(context.TODO(), portainerConfigMapName, metav1.GetOptions{})
|
||||
if k8serrors.IsNotFound(err) {
|
||||
return nil, nil
|
||||
} else if err != nil {
|
||||
@@ -50,7 +51,7 @@ func (kcl *KubeClient) setupNamespaceAccesses(userID int, teamIDs []int, service
|
||||
return err
|
||||
}
|
||||
|
||||
namespaces, err := kcl.cli.CoreV1().Namespaces().List(metav1.ListOptions{})
|
||||
namespaces, err := kcl.cli.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -105,7 +106,7 @@ func (kcl *KubeClient) UpdateNamespaceAccessPolicies(accessPolicies map[string]p
|
||||
return err
|
||||
}
|
||||
|
||||
configMap, err := kcl.cli.CoreV1().ConfigMaps(portainerNamespace).Get(portainerConfigMapName, metav1.GetOptions{})
|
||||
configMap, err := kcl.cli.CoreV1().ConfigMaps(portainerNamespace).Get(context.TODO(), portainerConfigMapName, metav1.GetOptions{})
|
||||
if k8serrors.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
@@ -115,7 +116,7 @@ func (kcl *KubeClient) UpdateNamespaceAccessPolicies(accessPolicies map[string]p
|
||||
}
|
||||
|
||||
configMap.Data[portainerConfigMapAccessPoliciesKey] = string(data)
|
||||
_, err = kcl.cli.CoreV1().ConfigMaps(portainerNamespace).Update(configMap)
|
||||
_, err = kcl.cli.CoreV1().ConfigMaps(portainerNamespace).Update(context.TODO(), configMap, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
@@ -51,10 +52,10 @@ func Test_NamespaceAccessPoliciesDeleteNamespace_updatesPortainerConfig_whenConf
|
||||
"NamespaceAccessPolicies": `{"ns1":{"UserAccessPolicies":{"2":{"RoleId":0}}}, "ns2":{"UserAccessPolicies":{"2":{"RoleId":0}}}}`,
|
||||
},
|
||||
}
|
||||
_, err := k.cli.CoreV1().ConfigMaps(portainerNamespace).Create(config)
|
||||
_, err := k.cli.CoreV1().ConfigMaps(portainerNamespace).Create(context.Background(), config, metav1.CreateOptions{})
|
||||
assert.NoError(t, err, "failed to create a portainer config")
|
||||
defer func() {
|
||||
k.cli.CoreV1().ConfigMaps(portainerNamespace).Delete(portainerConfigMapName, nil)
|
||||
k.cli.CoreV1().ConfigMaps(portainerNamespace).Delete(context.Background(), portainerConfigMapName, metav1.DeleteOptions{})
|
||||
}()
|
||||
|
||||
err = k.NamespaceAccessPoliciesDeleteNamespace(test.namespaceToDelete)
|
||||
|
||||
@@ -50,8 +50,8 @@ func Test_GetKubeConfig(t *testing.T) {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: tokenData.Username},
|
||||
}
|
||||
|
||||
k.cli.CoreV1().ServiceAccounts(portainerNamespace).Create(serviceAccount)
|
||||
defer k.cli.CoreV1().ServiceAccounts(portainerNamespace).Delete(serviceAccount.Name, nil)
|
||||
k.cli.CoreV1().ServiceAccounts(portainerNamespace).Create(context.Background(), serviceAccount, metav1.CreateOptions{})
|
||||
defer k.cli.CoreV1().ServiceAccounts(portainerNamespace).Delete(context.Background(), serviceAccount.Name, metav1.DeleteOptions{})
|
||||
|
||||
_, err := k.GetKubeConfig(context.Background(), "localhost", "abc", tokenData)
|
||||
|
||||
@@ -75,8 +75,8 @@ func Test_GetKubeConfig(t *testing.T) {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: nonAdminUserName},
|
||||
}
|
||||
|
||||
k.cli.CoreV1().ServiceAccounts(portainerNamespace).Create(serviceAccount)
|
||||
defer k.cli.CoreV1().ServiceAccounts(portainerNamespace).Delete(serviceAccount.Name, nil)
|
||||
k.cli.CoreV1().ServiceAccounts(portainerNamespace).Create(context.Background(), serviceAccount, metav1.CreateOptions{})
|
||||
defer k.cli.CoreV1().ServiceAccounts(portainerNamespace).Delete(context.Background(), serviceAccount.Name, metav1.DeleteOptions{})
|
||||
|
||||
_, err := k.GetKubeConfig(context.Background(), "localhost", "abc", tokenData)
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@@ -44,7 +45,7 @@ func (kcl *KubeClient) ToggleSystemState(namespaceName string, isSystem bool) er
|
||||
|
||||
nsService := kcl.cli.CoreV1().Namespaces()
|
||||
|
||||
namespace, err := nsService.Get(namespaceName, metav1.GetOptions{})
|
||||
namespace, err := nsService.Get(context.TODO(), namespaceName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed fetching namespace object")
|
||||
}
|
||||
@@ -59,7 +60,7 @@ func (kcl *KubeClient) ToggleSystemState(namespaceName string, isSystem bool) er
|
||||
|
||||
namespace.Labels[systemNamespaceLabel] = strconv.FormatBool(isSystem)
|
||||
|
||||
_, err = nsService.Update(namespace)
|
||||
_, err = nsService.Update(context.TODO(), namespace, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed updating namespace object")
|
||||
}
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
core "k8s.io/api/core/v1"
|
||||
ktypes "k8s.io/api/core/v1"
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
kfake "k8s.io/client-go/kubernetes/fake"
|
||||
)
|
||||
@@ -19,7 +17,7 @@ func Test_ToggleSystemState(t *testing.T) {
|
||||
t.Run("should skip is default (exit without error)", func(t *testing.T) {
|
||||
nsName := "default"
|
||||
kcl := &KubeClient{
|
||||
cli: kfake.NewSimpleClientset(&core.Namespace{ObjectMeta: meta.ObjectMeta{Name: nsName}}),
|
||||
cli: kfake.NewSimpleClientset(&core.Namespace{ObjectMeta: metav1.ObjectMeta{Name: nsName}}),
|
||||
instanceID: "instance",
|
||||
lock: &sync.Mutex{},
|
||||
}
|
||||
@@ -27,7 +25,7 @@ func Test_ToggleSystemState(t *testing.T) {
|
||||
err := kcl.ToggleSystemState(nsName, true)
|
||||
assert.NoError(t, err)
|
||||
|
||||
ns, err := kcl.cli.CoreV1().Namespaces().Get(nsName, meta.GetOptions{})
|
||||
ns, err := kcl.cli.CoreV1().Namespaces().Get(context.Background(), nsName, metav1.GetOptions{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, exists := ns.Labels[systemNamespaceLabel]
|
||||
@@ -59,7 +57,7 @@ func Test_ToggleSystemState(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(strconv.FormatBool(test.isSystem), func(t *testing.T) {
|
||||
kcl := &KubeClient{
|
||||
cli: kfake.NewSimpleClientset(&core.Namespace{ObjectMeta: meta.ObjectMeta{Name: nsName, Labels: map[string]string{
|
||||
cli: kfake.NewSimpleClientset(&core.Namespace{ObjectMeta: metav1.ObjectMeta{Name: nsName, Labels: map[string]string{
|
||||
systemNamespaceLabel: strconv.FormatBool(test.isSystem),
|
||||
}}}),
|
||||
instanceID: "instance",
|
||||
@@ -69,7 +67,7 @@ func Test_ToggleSystemState(t *testing.T) {
|
||||
err := kcl.ToggleSystemState(nsName, test.isSystem)
|
||||
assert.NoError(t, err)
|
||||
|
||||
ns, err := kcl.cli.CoreV1().Namespaces().Get(nsName, meta.GetOptions{})
|
||||
ns, err := kcl.cli.CoreV1().Namespaces().Get(context.Background(), nsName, metav1.GetOptions{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, test.isSystem, isSystemNamespace(*ns))
|
||||
@@ -81,7 +79,7 @@ func Test_ToggleSystemState(t *testing.T) {
|
||||
nsName := "namespace"
|
||||
|
||||
kcl := &KubeClient{
|
||||
cli: kfake.NewSimpleClientset(&core.Namespace{ObjectMeta: meta.ObjectMeta{Name: nsName}}),
|
||||
cli: kfake.NewSimpleClientset(&core.Namespace{ObjectMeta: metav1.ObjectMeta{Name: nsName}}),
|
||||
instanceID: "instance",
|
||||
lock: &sync.Mutex{},
|
||||
}
|
||||
@@ -89,7 +87,7 @@ func Test_ToggleSystemState(t *testing.T) {
|
||||
err := kcl.ToggleSystemState(nsName, true)
|
||||
assert.NoError(t, err)
|
||||
|
||||
ns, err := kcl.cli.CoreV1().Namespaces().Get(nsName, meta.GetOptions{})
|
||||
ns, err := kcl.cli.CoreV1().Namespaces().Get(context.Background(), nsName, metav1.GetOptions{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
labelValue, exists := ns.Labels[systemNamespaceLabel]
|
||||
@@ -102,7 +100,7 @@ func Test_ToggleSystemState(t *testing.T) {
|
||||
nsName := "portainer"
|
||||
|
||||
kcl := &KubeClient{
|
||||
cli: kfake.NewSimpleClientset(&core.Namespace{ObjectMeta: meta.ObjectMeta{Name: nsName}}),
|
||||
cli: kfake.NewSimpleClientset(&core.Namespace{ObjectMeta: metav1.ObjectMeta{Name: nsName}}),
|
||||
instanceID: "instance",
|
||||
lock: &sync.Mutex{},
|
||||
}
|
||||
@@ -110,7 +108,7 @@ func Test_ToggleSystemState(t *testing.T) {
|
||||
err := kcl.ToggleSystemState(nsName, false)
|
||||
assert.NoError(t, err)
|
||||
|
||||
ns, err := kcl.cli.CoreV1().Namespaces().Get(nsName, meta.GetOptions{})
|
||||
ns, err := kcl.cli.CoreV1().Namespaces().Get(context.Background(), nsName, metav1.GetOptions{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
labelValue, exists := ns.Labels[systemNamespaceLabel]
|
||||
@@ -123,7 +121,7 @@ func Test_ToggleSystemState(t *testing.T) {
|
||||
nsName := "namespace"
|
||||
|
||||
kcl := &KubeClient{
|
||||
cli: kfake.NewSimpleClientset(&core.Namespace{ObjectMeta: meta.ObjectMeta{Name: nsName, Labels: map[string]string{
|
||||
cli: kfake.NewSimpleClientset(&core.Namespace{ObjectMeta: metav1.ObjectMeta{Name: nsName, Labels: map[string]string{
|
||||
systemNamespaceLabel: "true",
|
||||
}}}),
|
||||
instanceID: "instance",
|
||||
@@ -133,7 +131,7 @@ func Test_ToggleSystemState(t *testing.T) {
|
||||
err := kcl.ToggleSystemState(nsName, false)
|
||||
assert.NoError(t, err)
|
||||
|
||||
ns, err := kcl.cli.CoreV1().Namespaces().Get(nsName, meta.GetOptions{})
|
||||
ns, err := kcl.cli.CoreV1().Namespaces().Get(context.Background(), nsName, metav1.GetOptions{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
labelValue, exists := ns.Labels[systemNamespaceLabel]
|
||||
@@ -144,11 +142,11 @@ func Test_ToggleSystemState(t *testing.T) {
|
||||
t.Run("for non system namespace (with label), if called with true, should set the label, and remove accesses", func(t *testing.T) {
|
||||
nsName := "ns1"
|
||||
|
||||
namespace := &core.Namespace{ObjectMeta: meta.ObjectMeta{Name: nsName, Labels: map[string]string{
|
||||
namespace := &core.Namespace{ObjectMeta: metav1.ObjectMeta{Name: nsName, Labels: map[string]string{
|
||||
systemNamespaceLabel: "false",
|
||||
}}}
|
||||
|
||||
config := &ktypes.ConfigMap{
|
||||
config := &core.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: portainerConfigMapName,
|
||||
Namespace: portainerNamespace,
|
||||
@@ -167,7 +165,7 @@ func Test_ToggleSystemState(t *testing.T) {
|
||||
err := kcl.ToggleSystemState(nsName, true)
|
||||
assert.NoError(t, err)
|
||||
|
||||
ns, err := kcl.cli.CoreV1().Namespaces().Get(nsName, meta.GetOptions{})
|
||||
ns, err := kcl.cli.CoreV1().Namespaces().Get(context.Background(), nsName, metav1.GetOptions{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
labelValue, exists := ns.Labels[systemNamespaceLabel]
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
@@ -9,12 +11,12 @@ import (
|
||||
func (kcl *KubeClient) GetNodesLimits() (portainer.K8sNodesLimits, error) {
|
||||
nodesLimits := make(portainer.K8sNodesLimits)
|
||||
|
||||
nodes, err := kcl.cli.CoreV1().Nodes().List(metav1.ListOptions{})
|
||||
nodes, err := kcl.cli.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pods, err := kcl.cli.CoreV1().Pods("").List(metav1.ListOptions{})
|
||||
pods, err := kcl.cli.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user