mirror of https://github.com/portainer/portainer
refactor(stacks): break swagger docs by type [EE-5381] (#8820)
parent
bbea0bc8a5
commit
77f8b9333a
|
@ -21,30 +21,8 @@ import (
|
|||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// @id CustomTemplateCreate
|
||||
// @summary Create a custom template
|
||||
// @description Create a custom template.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags custom_templates
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json,multipart/form-data
|
||||
// @produce json
|
||||
// @param method query string true "method for creating template" Enums(string, file, repository)
|
||||
// @param body_string body customTemplateFromFileContentPayload false "Required when using method=string"
|
||||
// @param body_repository body customTemplateFromGitRepositoryPayload false "Required when using method=repository"
|
||||
// @param Title formData string false "Title of the template. required when method is file"
|
||||
// @param Description formData string false "Description of the template. required when method is file"
|
||||
// @param Note formData string false "A note that will be displayed in the UI. Supports HTML content"
|
||||
// @param Platform formData int false "Platform associated to the template (1 - 'linux', 2 - 'windows'). required when method is file" Enums(1,2)
|
||||
// @param Type formData int false "Type of created stack (1 - swarm, 2 - compose), required when method is file" Enums(1,2)
|
||||
// @param file formData file false "required when method is file"
|
||||
// @success 200 {object} portainer.CustomTemplate
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 500 "Server error"
|
||||
// @router /custom_templates [post]
|
||||
func (handler *Handler) customTemplateCreate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
method, err := request.RetrieveQueryParameter(r, "method", false)
|
||||
method, err := request.RetrieveRouteVariableValue(r, "method")
|
||||
if err != nil {
|
||||
return httperror.BadRequest("Invalid query parameter: method", err)
|
||||
}
|
||||
|
@ -154,6 +132,20 @@ func isValidNote(note string) bool {
|
|||
return !match
|
||||
}
|
||||
|
||||
// @id CustomTemplateCreateString
|
||||
// @summary Create a custom template
|
||||
// @description Create a custom template.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags custom_templates
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param body body customTemplateFromFileContentPayload true "body"
|
||||
// @success 200 {object} portainer.CustomTemplate
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 500 "Server error"
|
||||
// @router /custom_templates/string [post]
|
||||
func (handler *Handler) createCustomTemplateFromFileContent(r *http.Request) (*portainer.CustomTemplate, error) {
|
||||
var payload customTemplateFromFileContentPayload
|
||||
err := request.DecodeAndValidateJSONPayload(r, &payload)
|
||||
|
@ -251,6 +243,20 @@ func (payload *customTemplateFromGitRepositoryPayload) Validate(r *http.Request)
|
|||
return validateVariablesDefinitions(payload.Variables)
|
||||
}
|
||||
|
||||
// @id CustomTemplateCreateRepository
|
||||
// @summary Create a custom template
|
||||
// @description Create a custom template.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags custom_templates
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param body body customTemplateFromGitRepositoryPayload true "Required when using method=repository"
|
||||
// @success 200 {object} portainer.CustomTemplate
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 500 "Server error"
|
||||
// @router /custom_templates/repository [post]
|
||||
func (handler *Handler) createCustomTemplateFromGitRepository(r *http.Request) (*portainer.CustomTemplate, error) {
|
||||
var payload customTemplateFromGitRepositoryPayload
|
||||
err := request.DecodeAndValidateJSONPayload(r, &payload)
|
||||
|
@ -405,6 +411,25 @@ func (payload *customTemplateFromFileUploadPayload) Validate(r *http.Request) er
|
|||
return nil
|
||||
}
|
||||
|
||||
// @id CustomTemplateCreateFile
|
||||
// @summary Create a custom template
|
||||
// @description Create a custom template.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags custom_templates
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept multipart/form-data
|
||||
// @produce json
|
||||
// @param Title formData string false "Title of the template"
|
||||
// @param Description formData string false "Description of the template"
|
||||
// @param Note formData string false "A note that will be displayed in the UI. Supports HTML content"
|
||||
// @param Platform formData int false "Platform associated to the template (1 - 'linux', 2 - 'windows')" Enums(1,2)
|
||||
// @param Type formData int false "Type of created stack (1 - swarm, 2 - compose)" Enums(1,2)
|
||||
// @param file formData file false "File"
|
||||
// @success 200 {object} portainer.CustomTemplate
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 500 "Server error"
|
||||
// @router /custom_templates/file [post]
|
||||
func (handler *Handler) createCustomTemplateFromFileUpload(r *http.Request) (*portainer.CustomTemplate, error) {
|
||||
payload := &customTemplateFromFileUploadPayload{}
|
||||
err := payload.Validate(r)
|
||||
|
|
|
@ -29,7 +29,8 @@ func NewHandler(bouncer *security.RequestBouncer, dataStore dataservices.DataSto
|
|||
GitService: gitService,
|
||||
gitFetchMutexs: make(map[portainer.TemplateID]*sync.Mutex),
|
||||
}
|
||||
h.Handle("/custom_templates",
|
||||
|
||||
h.Handle("/custom_templates/create/{method}",
|
||||
bouncer.AuthenticatedAccess(httperror.LoggerHandler(h.customTemplateCreate))).Methods(http.MethodPost)
|
||||
h.Handle("/custom_templates",
|
||||
bouncer.AuthenticatedAccess(httperror.LoggerHandler(h.customTemplateList))).Methods(http.MethodGet)
|
||||
|
|
|
@ -27,22 +27,8 @@ type edgeJobBasePayload struct {
|
|||
EdgeGroups []portainer.EdgeGroupID
|
||||
}
|
||||
|
||||
// @id EdgeJobCreate
|
||||
// @summary Create an EdgeJob
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param method query string true "Creation Method" Enums(file, string)
|
||||
// @param body_string body edgeJobCreateFromFileContentPayload true "EdgeGroup data when method is string"
|
||||
// @param body_file body edgeJobCreateFromFilePayload true "EdgeGroup data when method is file"
|
||||
// @success 200 {object} portainer.EdgeGroup
|
||||
// @failure 503 "Edge compute features are disabled"
|
||||
// @failure 500
|
||||
// @router /edge_jobs [post]
|
||||
func (handler *Handler) edgeJobCreate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
method, err := request.RetrieveQueryParameter(r, "method", false)
|
||||
method, err := request.RetrieveRouteVariableValue(r, "method")
|
||||
if err != nil {
|
||||
return httperror.BadRequest("Invalid query parameter: method. Valid values are: file or string", err)
|
||||
}
|
||||
|
@ -86,6 +72,18 @@ func (payload *edgeJobCreateFromFileContentPayload) Validate(r *http.Request) er
|
|||
return nil
|
||||
}
|
||||
|
||||
// @id EdgeJobCreateString
|
||||
// @summary Create an EdgeJob from a text
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param body body edgeJobCreateFromFileContentPayload true "EdgeGroup data when method is string"
|
||||
// @success 200 {object} portainer.EdgeGroup
|
||||
// @failure 503 "Edge compute features are disabled"
|
||||
// @failure 500
|
||||
// @router /edge_jobs/create/string [post]
|
||||
func (handler *Handler) createEdgeJobFromFileContent(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
var payload edgeJobCreateFromFileContentPayload
|
||||
err := request.DecodeAndValidateJSONPayload(r, &payload)
|
||||
|
@ -177,6 +175,24 @@ func (payload *edgeJobCreateFromFilePayload) Validate(r *http.Request) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// @id EdgeJobCreateFile
|
||||
// @summary Create an EdgeJob from a file
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_jobs
|
||||
// @accept multipart/form-data
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param file formData file true "Content of the Stack file"
|
||||
// @param Name formData string true "Name of the stack"
|
||||
// @param CronExpression formData string true "A cron expression to schedule this job"
|
||||
// @param EdgeGroups formData string true "JSON stringified array of Edge Groups ids"
|
||||
// @param Endpoints formData string true "JSON stringified array of Environment ids"
|
||||
// @param Recurring formData bool false "If recurring"
|
||||
// @success 200 {object} portainer.EdgeGroup
|
||||
// @failure 503 "Edge compute features are disabled"
|
||||
// @failure 500
|
||||
// @router /edge_jobs/create/file [post]
|
||||
func (handler *Handler) createEdgeJobFromFile(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
payload := &edgeJobCreateFromFilePayload{}
|
||||
err := payload.Validate(r)
|
||||
|
|
|
@ -28,7 +28,7 @@ func NewHandler(bouncer *security.RequestBouncer) *Handler {
|
|||
|
||||
h.Handle("/edge_jobs",
|
||||
bouncer.AdminAccess(bouncer.EdgeComputeOperation(httperror.LoggerHandler(h.edgeJobList)))).Methods(http.MethodGet)
|
||||
h.Handle("/edge_jobs",
|
||||
h.Handle("/edge_jobs/create/{method}",
|
||||
bouncer.AdminAccess(bouncer.EdgeComputeOperation(httperror.LoggerHandler(h.edgeJobCreate)))).Methods(http.MethodPost)
|
||||
h.Handle("/edge_jobs/{id}",
|
||||
bouncer.AdminAccess(bouncer.EdgeComputeOperation(httperror.LoggerHandler(h.edgeJobInspect)))).Methods(http.MethodGet)
|
||||
|
|
|
@ -23,23 +23,8 @@ func (e *InvalidPayloadError) Error() string {
|
|||
return e.msg
|
||||
}
|
||||
|
||||
// @id EdgeStackCreate
|
||||
// @summary Create an EdgeStack
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param method query string true "Creation Method" Enums(file,string,repository)
|
||||
// @param body_string body swarmStackFromFileContentPayload true "Required when using method=string"
|
||||
// @param body_file body swarmStackFromFileUploadPayload true "Required when using method=file"
|
||||
// @param body_repository body swarmStackFromGitRepositoryPayload true "Required when using method=repository"
|
||||
// @success 200 {object} portainer.EdgeStack
|
||||
// @failure 500
|
||||
// @failure 503 "Edge compute features are disabled"
|
||||
// @router /edge_stacks [post]
|
||||
func (handler *Handler) edgeStackCreate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
method, err := request.RetrieveQueryParameter(r, "method", false)
|
||||
method, err := request.RetrieveRouteVariableValue(r, "method")
|
||||
if err != nil {
|
||||
return httperror.BadRequest("Invalid query parameter: method", err)
|
||||
}
|
||||
|
@ -74,7 +59,7 @@ func (handler *Handler) createSwarmStack(method string, dryrun bool, userID port
|
|||
case "file":
|
||||
return handler.createSwarmStackFromFileUpload(r, dryrun)
|
||||
}
|
||||
return nil, errors.New("Invalid value for query parameter: method. Value must be one of: string, repository or file")
|
||||
return nil, &InvalidPayloadError{"Invalid value for query parameter: method. Value must be one of: string, repository or file"}
|
||||
}
|
||||
|
||||
type swarmStackFromFileContentPayload struct {
|
||||
|
@ -109,6 +94,19 @@ func (payload *swarmStackFromFileContentPayload) Validate(r *http.Request) error
|
|||
return nil
|
||||
}
|
||||
|
||||
// @id EdgeStackCreateString
|
||||
// @summary Create an EdgeStack from a text
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param body body swarmStackFromFileContentPayload true "stack config"
|
||||
// @param dryrun query string false "if true, will not create an edge stack, but just will check the settings and return a non-persisted edge stack object"
|
||||
// @success 200 {object} portainer.EdgeStack
|
||||
// @failure 500
|
||||
// @failure 503 "Edge compute features are disabled"
|
||||
// @router /edge_stacks/create/string [post]
|
||||
func (handler *Handler) createSwarmStackFromFileContent(r *http.Request, dryrun bool) (*portainer.EdgeStack, error) {
|
||||
var payload swarmStackFromFileContentPayload
|
||||
err := request.DecodeAndValidateJSONPayload(r, &payload)
|
||||
|
@ -229,6 +227,20 @@ func (payload *swarmStackFromGitRepositoryPayload) Validate(r *http.Request) err
|
|||
return nil
|
||||
}
|
||||
|
||||
// @id EdgeStackCreateRepository
|
||||
// @summary Create an EdgeStack from a git repository
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param method query string true "Creation Method" Enums(file,string,repository)
|
||||
// @param body body swarmStackFromGitRepositoryPayload true "stack config"
|
||||
// @param dryrun query string false "if true, will not create an edge stack, but just will check the settings and return a non-persisted edge stack object"
|
||||
// @success 200 {object} portainer.EdgeStack
|
||||
// @failure 500
|
||||
// @failure 503 "Edge compute features are disabled"
|
||||
// @router /edge_stacks/create/repository [post]
|
||||
func (handler *Handler) createSwarmStackFromGitRepository(r *http.Request, dryrun bool, userID portainer.UserID) (*portainer.EdgeStack, error) {
|
||||
var payload swarmStackFromGitRepositoryPayload
|
||||
err := request.DecodeAndValidateJSONPayload(r, &payload)
|
||||
|
@ -299,14 +311,14 @@ func (payload *swarmStackFromFileUploadPayload) Validate(r *http.Request) error
|
|||
}
|
||||
payload.EdgeGroups = edgeGroups
|
||||
|
||||
deploymentType, err := request.RetrieveNumericMultiPartFormValue(r, "DeploymentType", true)
|
||||
deploymentType, err := request.RetrieveNumericMultiPartFormValue(r, "DeploymentType", false)
|
||||
if err != nil {
|
||||
return &InvalidPayloadError{msg: "Invalid deployment type"}
|
||||
}
|
||||
payload.DeploymentType = portainer.EdgeStackDeploymentType(deploymentType)
|
||||
|
||||
var registries []portainer.RegistryID
|
||||
request.RetrieveMultiPartFormJSONValue(r, "Registries", ®istries, false)
|
||||
err = request.RetrieveMultiPartFormJSONValue(r, "Registries", ®istries, true)
|
||||
if err != nil {
|
||||
return errors.New("Invalid registry type")
|
||||
}
|
||||
|
@ -318,6 +330,27 @@ func (payload *swarmStackFromFileUploadPayload) Validate(r *http.Request) error
|
|||
return nil
|
||||
}
|
||||
|
||||
// @id EdgeStackCreateFile
|
||||
// @summary Create an EdgeStack from file
|
||||
// @description **Access policy**: administrator
|
||||
// @tags edge_stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept multipart/form-data
|
||||
// @produce json
|
||||
// @param Name formData string true "Name of the stack"
|
||||
// @param file formData file true "Content of the Stack file"
|
||||
// @param EdgeGroups formData string true "JSON stringified array of Edge Groups ids"
|
||||
// @param DeploymentType formData int true "deploy type 0 - 'compose', 1 - 'kubernetes', 2 - 'nomad'"
|
||||
// @param Registries formData string false "JSON stringified array of Registry ids to use for this stack"
|
||||
// @param UseManifestNamespaces formData bool false "Uses the manifest's namespaces instead of the default one, relevant only for kube environments"
|
||||
// @param PrePullImage formData bool false "Pre Pull image"
|
||||
// @param RetryDeploy formData bool false "Retry deploy"
|
||||
// @param dryrun query string false "if true, will not create an edge stack, but just will check the settings and return a non-persisted edge stack object"
|
||||
// @success 200 {object} portainer.EdgeStack
|
||||
// @failure 500
|
||||
// @failure 503 "Edge compute features are disabled"
|
||||
// @router /edge_stacks/create/file [post]
|
||||
func (handler *Handler) createSwarmStackFromFileUpload(r *http.Request, dryrun bool) (*portainer.EdgeStack, error) {
|
||||
payload := &swarmStackFromFileUploadPayload{}
|
||||
err := payload.Validate(r)
|
||||
|
|
|
@ -16,12 +16,13 @@ import (
|
|||
// @tags edge_stacks
|
||||
// @produce json
|
||||
// @param id path int true "EdgeStack Id"
|
||||
// @param environmentId path int true "Environment identifier"
|
||||
// @success 200 {object} portainer.EdgeStack
|
||||
// @failure 500
|
||||
// @failure 400
|
||||
// @failure 404
|
||||
// @failure 403
|
||||
// @router /edge_stacks/{id}/status/{endpoint_id} [delete]
|
||||
// @router /edge_stacks/{id}/status/{environmentId} [delete]
|
||||
func (handler *Handler) edgeStackStatusDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
stackID, err := request.RetrieveNumericRouteVariableValue(r, "id")
|
||||
if err != nil {
|
||||
|
|
|
@ -237,7 +237,7 @@ func TestCreateAndInspect(t *testing.T) {
|
|||
r := bytes.NewBuffer(jsonPayload)
|
||||
|
||||
// Create EdgeStack
|
||||
req, err := http.NewRequest(http.MethodPost, "/edge_stacks?method=string", r)
|
||||
req, err := http.NewRequest(http.MethodPost, "/edge_stacks/create/string", r)
|
||||
if err != nil {
|
||||
t.Fatal("request error:", err)
|
||||
}
|
||||
|
@ -290,37 +290,32 @@ func TestCreateWithInvalidPayload(t *testing.T) {
|
|||
cases := []struct {
|
||||
Name string
|
||||
Payload interface{}
|
||||
QueryString string
|
||||
ExpectedStatusCode int
|
||||
Method string
|
||||
}{
|
||||
{
|
||||
Name: "Invalid query string parameter",
|
||||
Name: "Invalid method parameter",
|
||||
Payload: swarmStackFromFileContentPayload{},
|
||||
QueryString: "invalid=query-string",
|
||||
Method: "invalid",
|
||||
ExpectedStatusCode: 400,
|
||||
},
|
||||
{
|
||||
Name: "Invalid creation method",
|
||||
Payload: swarmStackFromFileContentPayload{},
|
||||
QueryString: "method=invalid-creation-method",
|
||||
ExpectedStatusCode: 500,
|
||||
},
|
||||
|
||||
{
|
||||
Name: "Empty swarmStackFromFileContentPayload with string method",
|
||||
Payload: swarmStackFromFileContentPayload{},
|
||||
QueryString: "method=string",
|
||||
Method: "string",
|
||||
ExpectedStatusCode: 400,
|
||||
},
|
||||
{
|
||||
Name: "Empty swarmStackFromFileContentPayload with repository method",
|
||||
Payload: swarmStackFromFileContentPayload{},
|
||||
QueryString: "method=repository",
|
||||
Method: "repository",
|
||||
ExpectedStatusCode: 400,
|
||||
},
|
||||
{
|
||||
Name: "Empty swarmStackFromFileContentPayload with file method",
|
||||
Payload: swarmStackFromFileContentPayload{},
|
||||
QueryString: "method=file",
|
||||
Method: "file",
|
||||
ExpectedStatusCode: 400,
|
||||
},
|
||||
{
|
||||
|
@ -331,7 +326,7 @@ func TestCreateWithInvalidPayload(t *testing.T) {
|
|||
EdgeGroups: edgeStack.EdgeGroups,
|
||||
DeploymentType: edgeStack.DeploymentType,
|
||||
},
|
||||
QueryString: "method=string",
|
||||
Method: "string",
|
||||
ExpectedStatusCode: 500,
|
||||
},
|
||||
{
|
||||
|
@ -342,7 +337,7 @@ func TestCreateWithInvalidPayload(t *testing.T) {
|
|||
EdgeGroups: []portainer.EdgeGroupID{},
|
||||
DeploymentType: edgeStack.DeploymentType,
|
||||
},
|
||||
QueryString: "method=string",
|
||||
Method: "string",
|
||||
ExpectedStatusCode: 400,
|
||||
},
|
||||
{
|
||||
|
@ -353,7 +348,7 @@ func TestCreateWithInvalidPayload(t *testing.T) {
|
|||
EdgeGroups: []portainer.EdgeGroupID{1},
|
||||
DeploymentType: portainer.EdgeStackDeploymentKubernetes,
|
||||
},
|
||||
QueryString: "method=string",
|
||||
Method: "string",
|
||||
ExpectedStatusCode: 500,
|
||||
},
|
||||
{
|
||||
|
@ -364,7 +359,7 @@ func TestCreateWithInvalidPayload(t *testing.T) {
|
|||
EdgeGroups: []portainer.EdgeGroupID{1},
|
||||
DeploymentType: portainer.EdgeStackDeploymentCompose,
|
||||
},
|
||||
QueryString: "method=string",
|
||||
Method: "string",
|
||||
ExpectedStatusCode: 400,
|
||||
},
|
||||
{
|
||||
|
@ -380,7 +375,7 @@ func TestCreateWithInvalidPayload(t *testing.T) {
|
|||
EdgeGroups: []portainer.EdgeGroupID{1},
|
||||
DeploymentType: portainer.EdgeStackDeploymentCompose,
|
||||
},
|
||||
QueryString: "method=repository",
|
||||
Method: "repository",
|
||||
ExpectedStatusCode: 500,
|
||||
},
|
||||
}
|
||||
|
@ -394,7 +389,7 @@ func TestCreateWithInvalidPayload(t *testing.T) {
|
|||
r := bytes.NewBuffer(jsonPayload)
|
||||
|
||||
// Create EdgeStack
|
||||
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("/edge_stacks?%s", tc.QueryString), r)
|
||||
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("/edge_stacks/create/%s", tc.Method), r)
|
||||
if err != nil {
|
||||
t.Fatal("request error:", err)
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ func NewHandler(bouncer *security.RequestBouncer, dataStore dataservices.DataSto
|
|||
edgeStacksService: edgeStacksService,
|
||||
}
|
||||
|
||||
h.Handle("/edge_stacks",
|
||||
h.Handle("/edge_stacks/create/{method}",
|
||||
bouncer.AdminAccess(bouncer.EdgeComputeOperation(httperror.LoggerHandler(h.edgeStackCreate)))).Methods(http.MethodPost)
|
||||
h.Handle("/edge_stacks",
|
||||
bouncer.AdminAccess(bouncer.EdgeComputeOperation(httperror.LoggerHandler(h.edgeStackList)))).Methods(http.MethodGet)
|
||||
|
|
|
@ -192,7 +192,7 @@ func (payload *endpointCreatePayload) Validate(r *http.Request) error {
|
|||
// @param TagIds formData []int false "List of tag identifiers to which this environment(endpoint) is associated"
|
||||
// @param EdgeCheckinInterval formData int false "The check in interval for edge agent (in seconds)"
|
||||
// @param EdgeTunnelServerAddress formData string true "URL or IP address that will be used to establish a reverse tunnel"
|
||||
// @param Gpus formData array false "List of GPUs"
|
||||
// @param Gpus formData string false "List of GPUs - json stringified array of {name, value} structs"
|
||||
// @success 200 {object} portainer.Endpoint "Success"
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 500 "Server error"
|
||||
|
|
|
@ -54,6 +54,7 @@ func (payload *deviceConfigurePayload) Validate(r *http.Request) error {
|
|||
// @tags intel
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param guid path int true "Guid"
|
||||
// @param body body deviceConfigurePayload true "Device Configuration"
|
||||
// @success 200 "Success"
|
||||
// @failure 400 "Invalid request"
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
// @description **Access policy**: administrator
|
||||
// @tags intel
|
||||
// @security jwt
|
||||
// @param id path int true "FDO Profile identifier"
|
||||
// @produce json
|
||||
// @success 200 "Success"
|
||||
// @failure 400 "Invalid request"
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
// @tags intel
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "FDO Profile identifier"
|
||||
// @success 200 "Success"
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 500 "Server error"
|
||||
|
|
|
@ -22,6 +22,7 @@ type fdoProfileResponse struct {
|
|||
// @tags intel
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "FDO Profile identifier"
|
||||
// @success 200 "Success"
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 500 "Server error"
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
// @tags intel
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "FDO Profile identifier"
|
||||
// @success 200 "Success"
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 409 "Profile name already exists"
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
// @tags intel
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "Environment(Endpoint) identifier"
|
||||
// @param id path int true "Environment identifier"
|
||||
// @success 200 "Success"
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 403 "Permission denied to access settings"
|
||||
|
|
|
@ -80,6 +80,8 @@ func (payload *deviceActionPayload) Validate(r *http.Request) error {
|
|||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path int true "Environment identifier"
|
||||
// @param deviceId path int true "Device identifier"
|
||||
// @param body body deviceActionPayload true "Device Action"
|
||||
// @success 204 "Success"
|
||||
// @failure 400 "Invalid request"
|
||||
|
@ -140,6 +142,8 @@ type AuthorizationResponse struct {
|
|||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path int true "Environment identifier"
|
||||
// @param deviceId path int true "Device identifier"
|
||||
// @param body body deviceFeaturesPayload true "Device Features"
|
||||
// @success 204 "Success"
|
||||
// @failure 400 "Invalid request"
|
||||
|
|
|
@ -48,6 +48,7 @@ const (
|
|||
// @tags intel
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param id path int true "Environment identifier"
|
||||
// @success 200 "Success"
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 403 "Permission denied to access settings"
|
||||
|
|
|
@ -24,7 +24,7 @@ type composeStackFromFileContentPayload struct {
|
|||
Name string `example:"myStack" validate:"required"`
|
||||
// Content of the Stack file
|
||||
StackFileContent string `example:"version: 3\n services:\n web:\n image:nginx" validate:"required"`
|
||||
// A list of environment(endpoint) variables used during stack deployment
|
||||
// A list of environment variables used during stack deployment
|
||||
Env []portainer.Pair
|
||||
// Whether the stack is from a app template
|
||||
FromAppTemplate bool `example:"false"`
|
||||
|
@ -87,6 +87,21 @@ func (handler *Handler) checkAndCleanStackDupFromSwarm(w http.ResponseWriter, r
|
|||
return nil
|
||||
}
|
||||
|
||||
// @id StackCreateDockerStandaloneString
|
||||
// @summary Deploy a new compose stack from a text
|
||||
// @description Deploy a new stack into a Docker environment specified via the environment identifier.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param body body composeStackFromFileContentPayload true "stack config"
|
||||
// @param endpointId query int true "Identifier of the environment that will be used to deploy the stack"
|
||||
// @success 200 {object} portainer.Stack
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 500 "Server error"
|
||||
// @router /stacks/create/standalone/string [post]
|
||||
func (handler *Handler) createComposeStackFromFileContent(w http.ResponseWriter, r *http.Request, endpoint *portainer.Endpoint, userID portainer.UserID) *httperror.HandlerError {
|
||||
var payload composeStackFromFileContentPayload
|
||||
err := request.DecodeAndValidateJSONPayload(r, &payload)
|
||||
|
@ -158,7 +173,7 @@ type composeStackFromGitRepositoryPayload struct {
|
|||
AdditionalFiles []string `example:"[nz.compose.yml, uat.compose.yml]"`
|
||||
// Optional auto update configuration
|
||||
AutoUpdate *portainer.AutoUpdateSettings
|
||||
// A list of environment(endpoint) variables used during stack deployment
|
||||
// A list of environment variables used during stack deployment
|
||||
Env []portainer.Pair
|
||||
// Whether the stack is from a app template
|
||||
FromAppTemplate bool `example:"false"`
|
||||
|
@ -201,6 +216,21 @@ func (payload *composeStackFromGitRepositoryPayload) Validate(r *http.Request) e
|
|||
return nil
|
||||
}
|
||||
|
||||
// @id StackCreateDockerStandaloneRepository
|
||||
// @summary Deploy a new compose stack from repository
|
||||
// @description Deploy a new stack into a Docker environment specified via the environment identifier.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @accept json
|
||||
// @param endpointId query int true "Identifier of the environment that will be used to deploy the stack"
|
||||
// @param body body composeStackFromGitRepositoryPayload true "stack config"
|
||||
// @success 200 {object} portainer.Stack
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 500 "Server error"
|
||||
// @router /stacks/create/standalone/repository [post]
|
||||
func (handler *Handler) createComposeStackFromGitRepository(w http.ResponseWriter, r *http.Request, endpoint *portainer.Endpoint, userID portainer.UserID) *httperror.HandlerError {
|
||||
var payload composeStackFromGitRepositoryPayload
|
||||
err := request.DecodeAndValidateJSONPayload(r, &payload)
|
||||
|
@ -318,6 +348,23 @@ func decodeRequestForm(r *http.Request) (*composeStackFromFileUploadPayload, err
|
|||
return payload, nil
|
||||
}
|
||||
|
||||
// @id StackCreateDockerStandaloneFile
|
||||
// @summary Deploy a new compose stack from a file
|
||||
// @description Deploy a new stack into a Docker environment specified via the environment identifier.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept multipart/form-data
|
||||
// @produce json
|
||||
// @param Name formData string true "Name of the stack"
|
||||
// @param Env formData string false "Environment variables passed during deployment, represented as a JSON array [{'name': 'name', 'value': 'value'}]."
|
||||
// @param file formData file false "Stack file"
|
||||
// @param endpointId query int true "Identifier of the environment that will be used to deploy the stack"
|
||||
// @success 200 {object} portainer.Stack
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 500 "Server error"
|
||||
// @router /stacks/create/standalone/file [post]
|
||||
func (handler *Handler) createComposeStackFromFileUpload(w http.ResponseWriter, r *http.Request, endpoint *portainer.Endpoint, userID portainer.UserID) *httperror.HandlerError {
|
||||
payload, err := decodeRequestForm(r)
|
||||
if err != nil {
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/portainer/libhttp/response"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/git/update"
|
||||
"github.com/portainer/portainer/api/internal/endpointutils"
|
||||
k "github.com/portainer/portainer/api/kubernetes"
|
||||
"github.com/portainer/portainer/api/stacks/deployments"
|
||||
"github.com/portainer/portainer/api/stacks/stackbuilders"
|
||||
|
@ -131,7 +132,25 @@ type createKubernetesStackResponse struct {
|
|||
Output string `json:"Output"`
|
||||
}
|
||||
|
||||
// @id StackCreateKubernetesFile
|
||||
// @summary Deploy a new kubernetes stack from a file
|
||||
// @description Deploy a new stack into a Docker environment specified via the environment identifier.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param body body kubernetesStringDeploymentPayload true "stack config"
|
||||
// @param endpointId query int true "Identifier of the environment that will be used to deploy the stack"
|
||||
// @success 200 {object} portainer.Stack
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 500 "Server error"
|
||||
// @router /stacks/create/kubernetes/string [post]
|
||||
func (handler *Handler) createKubernetesStackFromFileContent(w http.ResponseWriter, r *http.Request, endpoint *portainer.Endpoint, userID portainer.UserID) *httperror.HandlerError {
|
||||
if !endpointutils.IsKubernetesEndpoint(endpoint) {
|
||||
return httperror.BadRequest("Environment type does not match", errors.New("Environment type does not match"))
|
||||
}
|
||||
|
||||
var payload kubernetesStringDeploymentPayload
|
||||
if err := request.DecodeAndValidateJSONPayload(r, &payload); err != nil {
|
||||
return httperror.BadRequest("Invalid request payload", err)
|
||||
|
@ -170,7 +189,25 @@ func (handler *Handler) createKubernetesStackFromFileContent(w http.ResponseWrit
|
|||
return response.JSON(w, resp)
|
||||
}
|
||||
|
||||
// @id StackCreateKubernetesGit
|
||||
// @summary Deploy a new kubernetes stack from a git repository
|
||||
// @description Deploy a new stack into a Docker environment specified via the environment identifier.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param body body kubernetesGitDeploymentPayload true "stack config"
|
||||
// @param endpointId query int true "Identifier of the environment that will be used to deploy the stack"
|
||||
// @success 200 {object} portainer.Stack
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 500 "Server error"
|
||||
// @router /stacks/create/kubernetes/repository [post]
|
||||
func (handler *Handler) createKubernetesStackFromGitRepository(w http.ResponseWriter, r *http.Request, endpoint *portainer.Endpoint, userID portainer.UserID) *httperror.HandlerError {
|
||||
if !endpointutils.IsKubernetesEndpoint(endpoint) {
|
||||
return httperror.BadRequest("Environment type does not match", errors.New("Environment type does not match"))
|
||||
}
|
||||
|
||||
var payload kubernetesGitDeploymentPayload
|
||||
if err := request.DecodeAndValidateJSONPayload(r, &payload); err != nil {
|
||||
return httperror.BadRequest("Invalid request payload", err)
|
||||
|
@ -234,6 +271,20 @@ func (handler *Handler) createKubernetesStackFromGitRepository(w http.ResponseWr
|
|||
return response.JSON(w, resp)
|
||||
}
|
||||
|
||||
// @id StackCreateKubernetesUrl
|
||||
// @summary Deploy a new kubernetes stack from a url
|
||||
// @description Deploy a new stack into a Docker environment specified via the environment identifier.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @param body body kubernetesManifestURLDeploymentPayload true "stack config"
|
||||
// @param endpointId query int true "Identifier of the environment that will be used to deploy the stack"
|
||||
// @success 200 {object} portainer.Stack
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 500 "Server error"
|
||||
// @router /stacks/create/kubernetes/url [post]
|
||||
func (handler *Handler) createKubernetesStackFromManifestURL(w http.ResponseWriter, r *http.Request, endpoint *portainer.Endpoint, userID portainer.UserID) *httperror.HandlerError {
|
||||
var payload kubernetesManifestURLDeploymentPayload
|
||||
if err := request.DecodeAndValidateJSONPayload(r, &payload); err != nil {
|
||||
|
|
|
@ -23,7 +23,7 @@ type swarmStackFromFileContentPayload struct {
|
|||
SwarmID string `example:"jpofkc0i9uo9wtx1zesuk649w" validate:"required"`
|
||||
// Content of the Stack file
|
||||
StackFileContent string `example:"version: 3\n services:\n web:\n image:nginx" validate:"required"`
|
||||
// A list of environment(endpoint) variables used during stack deployment
|
||||
// A list of environment variables used during stack deployment
|
||||
Env []portainer.Pair
|
||||
// Whether the stack is from a app template
|
||||
FromAppTemplate bool `example:"false"`
|
||||
|
@ -52,6 +52,21 @@ func createStackPayloadFromSwarmFileContentPayload(name string, swarmID string,
|
|||
}
|
||||
}
|
||||
|
||||
// @id StackCreateDockerSwarmString
|
||||
// @summary Deploy a new swarm stack from a text
|
||||
// @description Deploy a new stack into a Docker environment specified via the environment identifier.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param body body swarmStackFromFileContentPayload true "stack config"
|
||||
// @param endpointId query int true "Identifier of the environment that will be used to deploy the stack"
|
||||
// @success 200 {object} portainer.Stack
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 500 "Server error"
|
||||
// @router /stacks/create/swarm/string [post]
|
||||
func (handler *Handler) createSwarmStackFromFileContent(w http.ResponseWriter, r *http.Request, endpoint *portainer.Endpoint, userID portainer.UserID) *httperror.HandlerError {
|
||||
var payload swarmStackFromFileContentPayload
|
||||
err := request.DecodeAndValidateJSONPayload(r, &payload)
|
||||
|
@ -96,7 +111,7 @@ type swarmStackFromGitRepositoryPayload struct {
|
|||
Name string `example:"myStack" validate:"required"`
|
||||
// Swarm cluster identifier
|
||||
SwarmID string `example:"jpofkc0i9uo9wtx1zesuk649w" validate:"required"`
|
||||
// A list of environment(endpoint) variables used during stack deployment
|
||||
// A list of environment variables used during stack deployment
|
||||
Env []portainer.Pair
|
||||
|
||||
// URL of a Git repository hosting the Stack file
|
||||
|
@ -159,6 +174,21 @@ func createStackPayloadFromSwarmGitPayload(name, swarmID, repoUrl, repoReference
|
|||
}
|
||||
}
|
||||
|
||||
// @id StackCreateDockerSwarmRepository
|
||||
// @summary Deploy a new swarm stack from a git repository
|
||||
// @description Deploy a new stack into a Docker environment specified via the environment identifier.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @produce json
|
||||
// @accept json
|
||||
// @param endpointId query int true "Identifier of the environment that will be used to deploy the stack"
|
||||
// @param body body swarmStackFromGitRepositoryPayload true "stack config"
|
||||
// @success 200 {object} portainer.Stack
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 500 "Server error"
|
||||
// @router /stacks/create/swarm/repository [post]
|
||||
func (handler *Handler) createSwarmStackFromGitRepository(w http.ResponseWriter, r *http.Request, endpoint *portainer.Endpoint, userID portainer.UserID) *httperror.HandlerError {
|
||||
var payload swarmStackFromGitRepositoryPayload
|
||||
err := request.DecodeAndValidateJSONPayload(r, &payload)
|
||||
|
@ -267,8 +297,26 @@ func (payload *swarmStackFromFileUploadPayload) Validate(r *http.Request) error
|
|||
return nil
|
||||
}
|
||||
|
||||
// @id StackCreateDockerSwarmFile
|
||||
// @summary Deploy a new swarm stack from a file
|
||||
// @description Deploy a new stack into a Docker environment specified via the environment identifier.
|
||||
// @description **Access policy**: authenticated
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept multipart/form-data
|
||||
// @produce json
|
||||
// @param Name formData string false "Name of the stack"
|
||||
// @param SwarmID formData string false "Swarm cluster identifier."
|
||||
// @param Env formData string false "Environment variables passed during deployment, represented as a JSON array [{'name': 'name', 'value': 'value'}]. Optional"
|
||||
// @param file formData file false "Stack file"
|
||||
// @param endpointId query int true "Identifier of the environment that will be used to deploy the stack"
|
||||
// @success 200 {object} portainer.Stack
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 500 "Server error"
|
||||
// @router /stacks/create/swarm/file [post]
|
||||
func (handler *Handler) createSwarmStackFromFileUpload(w http.ResponseWriter, r *http.Request, endpoint *portainer.Endpoint, userID portainer.UserID) *httperror.HandlerError {
|
||||
payload := &swarmStackFromFileUploadPayload{}
|
||||
var payload swarmStackFromFileUploadPayload
|
||||
err := payload.Validate(r)
|
||||
if err != nil {
|
||||
return httperror.BadRequest("Invalid request payload", err)
|
||||
|
|
|
@ -55,7 +55,8 @@ func NewHandler(bouncer *security.RequestBouncer) *Handler {
|
|||
stackDeletionMutex: &sync.Mutex{},
|
||||
requestBouncer: bouncer,
|
||||
}
|
||||
h.Handle("/stacks",
|
||||
|
||||
h.Handle("/stacks/create/{type}/{method}",
|
||||
bouncer.AuthenticatedAccess(httperror.LoggerHandler(h.stackCreate))).Methods(http.MethodPost)
|
||||
h.Handle("/stacks",
|
||||
bouncer.AuthenticatedAccess(httperror.LoggerHandler(h.stackList))).Methods(http.MethodGet)
|
||||
|
|
|
@ -13,42 +13,15 @@ import (
|
|||
"github.com/portainer/portainer/api/stacks/stackutils"
|
||||
)
|
||||
|
||||
// @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**: authenticated
|
||||
// @tags stacks
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
// @accept json,multipart/form-data
|
||||
// @produce json
|
||||
// @param type query int true "Stack deployment type. Possible values: 1 (Swarm stack), 2 (Compose stack) or 3 (Kubernetes stack)." Enums(1,2,3)
|
||||
// @param method query string true "Stack deployment method. Possible values: file, string, repository or url." Enums(string, file, repository, url)
|
||||
// @param endpointId query int true "Identifier of the environment(endpoint) that will be used to deploy the stack"
|
||||
// @param body_swarm_string body swarmStackFromFileContentPayload false "Required when using method=string and type=1"
|
||||
// @param body_swarm_repository body swarmStackFromGitRepositoryPayload false "Required when using method=repository and type=1"
|
||||
// @param body_compose_string body composeStackFromFileContentPayload false "Required when using method=string and type=2"
|
||||
// @param body_compose_repository body composeStackFromGitRepositoryPayload false "Required when using method=repository and type=2"
|
||||
// @param body_kubernetes_string body kubernetesStringDeploymentPayload false "Required when using method=string and type=3"
|
||||
// @param body_kubernetes_repository body kubernetesGitDeploymentPayload false "Required when using method=repository and type=3"
|
||||
// @param body_kubernetes_url body kubernetesManifestURLDeploymentPayload false "Required when using method=url and type=3"
|
||||
// @param Name formData string false "Name of the stack. required when method is file"
|
||||
// @param SwarmID formData string false "Swarm cluster identifier. Required when method equals file and type equals 1. required when method is file"
|
||||
// @param Env formData string false "Environment(Endpoint) variables passed during deployment, represented as a JSON array [{'name': 'name', 'value': 'value'}]. Optional, used when method equals file and type equals 1."
|
||||
// @param file formData file false "Stack file. required when method is file"
|
||||
// @success 200 {object} portainer.CustomTemplate
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 500 "Server error"
|
||||
// @router /stacks [post]
|
||||
func (handler *Handler) stackCreate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
stackType, err := request.RetrieveNumericQueryParameter(r, "type", false)
|
||||
stackType, err := request.RetrieveRouteVariableValue(r, "type")
|
||||
if err != nil {
|
||||
return httperror.BadRequest("Invalid query parameter: type", err)
|
||||
return httperror.BadRequest("Invalid path parameter: type", err)
|
||||
}
|
||||
|
||||
method, err := request.RetrieveQueryParameter(r, "method", false)
|
||||
method, err := request.RetrieveRouteVariableValue(r, "method")
|
||||
if err != nil {
|
||||
return httperror.BadRequest("Invalid query parameter: method", err)
|
||||
return httperror.BadRequest("Invalid path parameter: method", err)
|
||||
}
|
||||
|
||||
endpointID, err := request.RetrieveNumericQueryParameter(r, "endpointId", false)
|
||||
|
@ -87,12 +60,12 @@ func (handler *Handler) stackCreate(w http.ResponseWriter, r *http.Request) *htt
|
|||
return httperror.InternalServerError("Unable to retrieve user details from authentication token", err)
|
||||
}
|
||||
|
||||
switch portainer.StackType(stackType) {
|
||||
case portainer.DockerSwarmStack:
|
||||
switch stackType {
|
||||
case "swarm":
|
||||
return handler.createSwarmStack(w, r, method, endpoint, tokenData.ID)
|
||||
case portainer.DockerComposeStack:
|
||||
case "standalone":
|
||||
return handler.createComposeStack(w, r, method, endpoint, tokenData.ID)
|
||||
case portainer.KubernetesStack:
|
||||
case "kubernetes":
|
||||
return handler.createKubernetesStack(w, r, method, endpoint, tokenData.ID)
|
||||
}
|
||||
|
||||
|
|
|
@ -20,11 +20,11 @@ import (
|
|||
// @description Acts on a passed in token UUID to restart the docker service
|
||||
// @description **Access policy**: public
|
||||
// @tags webhooks
|
||||
// @param token path string true "Webhook token"
|
||||
// @param id path string true "Webhook token"
|
||||
// @success 202 "Webhook executed"
|
||||
// @failure 400
|
||||
// @failure 500
|
||||
// @router /webhooks/{token} [post]
|
||||
// @router /webhooks/{id} [post]
|
||||
func (handler *Handler) webhookExecute(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
|
||||
webhookToken, err := request.RetrieveRouteVariableValue(r, "token")
|
||||
|
|
|
@ -28,6 +28,7 @@ func (payload *webhookUpdatePayload) Validate(r *http.Request) error {
|
|||
// @tags webhooks
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @param id path int true "Webhook id"
|
||||
// @param body body webhookUpdatePayload true "Webhook data"
|
||||
// @success 200 {object} portainer.Webhook
|
||||
// @failure 400
|
||||
|
|
|
@ -5,7 +5,7 @@ function EdgeJobsFactory($resource, API_ENDPOINT_EDGE_JOBS) {
|
|||
API_ENDPOINT_EDGE_JOBS + '/:id/:action',
|
||||
{},
|
||||
{
|
||||
create: { method: 'POST' },
|
||||
create: { method: 'POST', params: { id: 'create', action: '@method' } },
|
||||
query: { method: 'GET', isArray: true },
|
||||
get: { method: 'GET', params: { id: '@id' } },
|
||||
update: { method: 'PUT', params: { id: '@id' } },
|
||||
|
|
|
@ -5,7 +5,7 @@ angular.module('portainer.edge').factory('EdgeStacks', function EdgeStacksFactor
|
|||
API_ENDPOINT_EDGE_STACKS + '/:id/:action',
|
||||
{},
|
||||
{
|
||||
create: { method: 'POST', ignoreLoadingBar: true },
|
||||
create: { method: 'POST', ignoreLoadingBar: true, params: { id: 'create', action: '@method' } },
|
||||
query: { method: 'GET', isArray: true },
|
||||
get: { method: 'GET', params: { id: '@id' } },
|
||||
update: { method: 'PUT', params: { id: '@id' } },
|
||||
|
|
|
@ -49,7 +49,7 @@ function EdgeJobService(EdgeJobs, EdgeJobResults, FileUploadService) {
|
|||
|
||||
service.createEdgeJobFromFileContent = function (model) {
|
||||
var payload = new ScheduleCreateRequest(model);
|
||||
return EdgeJobs.create({ method: 'string' }, payload).$promise;
|
||||
return EdgeJobs.create({}, { method: 'string', ...payload }).$promise;
|
||||
};
|
||||
|
||||
service.createEdgeJobFromFileUpload = function (model) {
|
||||
|
|
|
@ -30,7 +30,7 @@ angular.module('portainer.edge').factory('EdgeStackService', function EdgeStackS
|
|||
|
||||
service.createStackFromFileContent = async function createStackFromFileContent(payload) {
|
||||
try {
|
||||
return await EdgeStacks.create({ method: 'string' }, payload).$promise;
|
||||
return await EdgeStacks.create({}, { method: 'string', ...payload }).$promise;
|
||||
} catch (err) {
|
||||
throw { msg: 'Unable to create the stack', err };
|
||||
}
|
||||
|
@ -47,9 +47,10 @@ angular.module('portainer.edge').factory('EdgeStackService', function EdgeStackS
|
|||
service.createStackFromGitRepository = async function createStackFromGitRepository(payload, repositoryOptions) {
|
||||
try {
|
||||
return await EdgeStacks.create(
|
||||
{ method: 'repository' },
|
||||
{},
|
||||
{
|
||||
...payload,
|
||||
method: 'repository',
|
||||
RepositoryURL: repositoryOptions.RepositoryURL,
|
||||
RepositoryReferenceName: repositoryOptions.RepositoryReferenceName,
|
||||
FilePathInRepository: repositoryOptions.FilePathInRepository,
|
||||
|
|
|
@ -7,7 +7,7 @@ function CustomTemplatesFactory($resource, API_ENDPOINT_CUSTOM_TEMPLATES) {
|
|||
API_ENDPOINT_CUSTOM_TEMPLATES + '/:id/:action',
|
||||
{},
|
||||
{
|
||||
create: { method: 'POST', ignoreLoadingBar: true },
|
||||
create: { method: 'POST', ignoreLoadingBar: true, params: { id: 'create', action: '@method' } },
|
||||
query: { method: 'GET', isArray: true },
|
||||
get: { method: 'GET', params: { id: '@id' } },
|
||||
update: { method: 'PUT', params: { id: '@id' } },
|
||||
|
|
|
@ -10,7 +10,7 @@ function StackFactory($resource, API_ENDPOINT_STACKS) {
|
|||
{
|
||||
get: { method: 'GET', params: { id: '@id' } },
|
||||
query: { method: 'GET', isArray: true },
|
||||
create: { method: 'POST', ignoreLoadingBar: true },
|
||||
create: { method: 'POST', ignoreLoadingBar: true, params: { id: 'create', subaction: '@method', action: '@type' } },
|
||||
update: { method: 'PUT', params: { id: '@id' }, ignoreLoadingBar: true },
|
||||
associate: { method: 'PUT', params: { id: '@id', swarmId: '@swarmId', endpointId: '@endpointId', orphanedRunning: '@orphanedRunning', action: 'associate' } },
|
||||
remove: { method: 'DELETE', params: { id: '@id', external: '@external', endpointId: '@endpointId' } },
|
||||
|
|
|
@ -40,7 +40,7 @@ function CustomTemplateServiceFactory($sanitize, CustomTemplates, FileUploadServ
|
|||
|
||||
service.createCustomTemplateFromFileContent = async function createCustomTemplateFromFileContent(payload) {
|
||||
try {
|
||||
return await CustomTemplates.create({ method: 'string' }, payload).$promise;
|
||||
return await CustomTemplates.create({}, { method: 'string', ...payload }).$promise;
|
||||
} catch (err) {
|
||||
throw { msg: 'Unable to create the customTemplate', err };
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ function CustomTemplateServiceFactory($sanitize, CustomTemplates, FileUploadServ
|
|||
|
||||
service.createCustomTemplateFromGitRepository = async function createCustomTemplateFromGitRepository(payload) {
|
||||
try {
|
||||
return await CustomTemplates.create({ method: 'repository' }, payload).$promise;
|
||||
return await CustomTemplates.create({}, { method: 'repository', ...payload }).$promise;
|
||||
} catch (err) {
|
||||
throw { msg: 'Unable to create the customTemplate', err };
|
||||
}
|
||||
|
|
|
@ -317,7 +317,7 @@ angular.module('portainer.app').factory('StackService', [
|
|||
StackFileContent: stackFileContent,
|
||||
Env: env,
|
||||
};
|
||||
return Stack.create({ method: 'string', type: 2, endpointId: endpointId }, payload).$promise;
|
||||
return Stack.create({ endpointId: endpointId }, { method: 'string', type: 'standalone', ...payload }).$promise;
|
||||
};
|
||||
|
||||
service.createSwarmStackFromFileContent = function (name, stackFileContent, env, endpointId) {
|
||||
|
@ -331,7 +331,7 @@ angular.module('portainer.app').factory('StackService', [
|
|||
StackFileContent: stackFileContent,
|
||||
Env: env,
|
||||
};
|
||||
return Stack.create({ method: 'string', type: 1, endpointId: endpointId }, payload).$promise;
|
||||
return Stack.create({ endpointId: endpointId }, { method: 'string', type: 'swarm', ...payload }).$promise;
|
||||
})
|
||||
.then(function success(data) {
|
||||
deferred.resolve(data);
|
||||
|
@ -362,7 +362,7 @@ angular.module('portainer.app').factory('StackService', [
|
|||
payload.AutoUpdate = repositoryOptions.AutoUpdate;
|
||||
}
|
||||
|
||||
return Stack.create({ method: 'repository', type: 2, endpointId: endpointId }, payload).$promise;
|
||||
return Stack.create({ endpointId: endpointId }, { method: 'repository', type: 'standalone', ...payload }).$promise;
|
||||
};
|
||||
|
||||
service.createSwarmStackFromGitRepository = function (name, repositoryOptions, env, endpointId) {
|
||||
|
@ -390,7 +390,7 @@ angular.module('portainer.app').factory('StackService', [
|
|||
payload.AutoUpdate = repositoryOptions.AutoUpdate;
|
||||
}
|
||||
|
||||
return Stack.create({ method: 'repository', type: 1, endpointId: endpointId }, payload).$promise;
|
||||
return Stack.create({ endpointId: endpointId }, { method: 'repository', type: 'swarm', ...payload }).$promise;
|
||||
})
|
||||
.then(function success(data) {
|
||||
deferred.resolve(data);
|
||||
|
@ -409,7 +409,7 @@ angular.module('portainer.app').factory('StackService', [
|
|||
|
||||
async function kubernetesDeployAsync(endpointId, method, payload) {
|
||||
try {
|
||||
await Stack.create({ endpointId: endpointId, method: method, type: 3 }, payload).$promise;
|
||||
await Stack.create({ endpointId: endpointId }, { method, type: 'kubernetes', ...payload }).$promise;
|
||||
} catch (err) {
|
||||
throw { err: err };
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ angular.module('portainer.app').factory('FileUploadService', [
|
|||
|
||||
service.createSchedule = function (payload) {
|
||||
return Upload.upload({
|
||||
url: 'api/edge_jobs?method=file',
|
||||
url: 'api/edge_jobs/create/file',
|
||||
data: {
|
||||
file: payload.File,
|
||||
Name: payload.Name,
|
||||
|
@ -90,7 +90,7 @@ angular.module('portainer.app').factory('FileUploadService', [
|
|||
|
||||
service.createSwarmStack = function (stackName, swarmId, file, env, endpointId) {
|
||||
return Upload.upload({
|
||||
url: 'api/stacks?method=file&type=1&endpointId=' + endpointId,
|
||||
url: `api/stacks/create/swarm/file?endpointId=${endpointId}`,
|
||||
data: {
|
||||
file: file,
|
||||
Name: stackName,
|
||||
|
@ -103,7 +103,7 @@ angular.module('portainer.app').factory('FileUploadService', [
|
|||
|
||||
service.createComposeStack = function (stackName, file, env, endpointId) {
|
||||
return Upload.upload({
|
||||
url: 'api/stacks?method=file&type=2&endpointId=' + endpointId,
|
||||
url: `api/stacks/create/standalone/file?endpointId=${endpointId}`,
|
||||
data: {
|
||||
file: file,
|
||||
Name: stackName,
|
||||
|
@ -115,7 +115,7 @@ angular.module('portainer.app').factory('FileUploadService', [
|
|||
|
||||
service.createEdgeStack = function createEdgeStack({ EdgeGroups, ...payload }, file) {
|
||||
return Upload.upload({
|
||||
url: 'api/edge_stacks?method=file',
|
||||
url: `api/edge_stacks/create/file`,
|
||||
data: {
|
||||
file,
|
||||
EdgeGroups: Upload.json(EdgeGroups),
|
||||
|
@ -127,7 +127,7 @@ angular.module('portainer.app').factory('FileUploadService', [
|
|||
|
||||
service.createCustomTemplate = function createCustomTemplate(data) {
|
||||
return Upload.upload({
|
||||
url: 'api/custom_templates?method=file',
|
||||
url: 'api/custom_templates/create/file',
|
||||
data,
|
||||
ignoreLoadingBar: true,
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue