diff --git a/api/http/handler/customtemplates/customtemplate_create.go b/api/http/handler/customtemplates/customtemplate_create.go index a5b6ecdee..0f9c8f1a3 100644 --- a/api/http/handler/customtemplates/customtemplate_create.go +++ b/api/http/handler/customtemplates/customtemplate_create.go @@ -482,28 +482,3 @@ func (handler *Handler) createCustomTemplateFromFileUpload(r *http.Request) (*po return customTemplate, nil } - -// @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 body object true "for body documentation see the relevant /custom_templates/{method} endpoint" -// @success 200 {object} portainer.CustomTemplate -// @failure 400 "Invalid request" -// @failure 500 "Server error" -// @deprecated -// @router /custom_templates [post] -func deprecatedCustomTemplateCreateUrlParser(w http.ResponseWriter, r *http.Request) (string, *httperror.HandlerError) { - method, err := request.RetrieveQueryParameter(r, "method", false) - if err != nil { - return "", httperror.BadRequest("Invalid query parameter: method", err) - } - - return "/custom_templates/create/" + method, nil -} diff --git a/api/http/handler/customtemplates/handler.go b/api/http/handler/customtemplates/handler.go index 1bb148af6..0da63d81f 100644 --- a/api/http/handler/customtemplates/handler.go +++ b/api/http/handler/customtemplates/handler.go @@ -7,7 +7,6 @@ import ( "github.com/gorilla/mux" portainer "github.com/portainer/portainer/api" "github.com/portainer/portainer/api/dataservices" - "github.com/portainer/portainer/api/http/middlewares" "github.com/portainer/portainer/api/http/security" httperror "github.com/portainer/portainer/pkg/libhttp/error" ) @@ -33,7 +32,6 @@ func NewHandler(bouncer security.BouncerService, dataStore dataservices.DataStor h.Handle("/custom_templates/create/{method}", bouncer.AuthenticatedAccess(httperror.LoggerHandler(h.customTemplateCreate))).Methods(http.MethodPost) - h.Handle("/custom_templates", middlewares.Deprecated(h, deprecatedCustomTemplateCreateUrlParser)).Methods(http.MethodPost) // Deprecated h.Handle("/custom_templates", bouncer.AuthenticatedAccess(httperror.LoggerHandler(h.customTemplateList))).Methods(http.MethodGet) h.Handle("/custom_templates/{id}", diff --git a/api/http/handler/edgejobs/edgejob_create.go b/api/http/handler/edgejobs/edgejob_create.go index 252770aa2..0f7bff73d 100644 --- a/api/http/handler/edgejobs/edgejob_create.go +++ b/api/http/handler/edgejobs/edgejob_create.go @@ -271,26 +271,3 @@ func (handler *Handler) addAndPersistEdgeJob(tx dataservices.DataStoreTx, edgeJo return tx.EdgeJob().CreateWithID(edgeJob.ID, edgeJob) } - -// @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 body object true "for body documentation see the relevant /edge_jobs/create/{method} endpoint" -// @success 200 {object} portainer.EdgeGroup -// @failure 503 "Edge compute features are disabled" -// @failure 500 -// @deprecated -// @router /edge_jobs [post] -func deprecatedEdgeJobCreateUrlParser(w http.ResponseWriter, r *http.Request) (string, *httperror.HandlerError) { - method, err := request.RetrieveQueryParameter(r, "method", false) - if err != nil { - return "", httperror.BadRequest("Invalid query parameter: method. Valid values are: file or string", err) - } - - return "/edge_jobs/create/" + method, nil -} diff --git a/api/http/handler/edgejobs/handler.go b/api/http/handler/edgejobs/handler.go index 93f210bb5..ab3d66b3b 100644 --- a/api/http/handler/edgejobs/handler.go +++ b/api/http/handler/edgejobs/handler.go @@ -6,7 +6,6 @@ import ( portainer "github.com/portainer/portainer/api" "github.com/portainer/portainer/api/dataservices" - "github.com/portainer/portainer/api/http/middlewares" "github.com/portainer/portainer/api/http/security" httperror "github.com/portainer/portainer/pkg/libhttp/error" "github.com/portainer/portainer/pkg/libhttp/response" @@ -30,8 +29,6 @@ func NewHandler(bouncer security.BouncerService) *Handler { h.Handle("/edge_jobs", bouncer.AdminAccess(bouncer.EdgeComputeOperation(httperror.LoggerHandler(h.edgeJobList)))).Methods(http.MethodGet) - h.Handle("/edge_jobs", - bouncer.AdminAccess(bouncer.EdgeComputeOperation(middlewares.Deprecated(h, deprecatedEdgeJobCreateUrlParser)))).Methods(http.MethodPost) h.Handle("/edge_jobs/create/{method}", bouncer.AdminAccess(bouncer.EdgeComputeOperation(httperror.LoggerHandler(h.edgeJobCreate)))).Methods(http.MethodPost) h.Handle("/edge_jobs/{id}", diff --git a/api/http/handler/edgestacks/edgestack_create.go b/api/http/handler/edgestacks/edgestack_create.go index 12dfe620a..65e77764a 100644 --- a/api/http/handler/edgestacks/edgestack_create.go +++ b/api/http/handler/edgestacks/edgestack_create.go @@ -55,26 +55,3 @@ func (handler *Handler) createSwarmStack(tx dataservices.DataStoreTx, method str return nil, httperrors.NewInvalidPayloadError("Invalid value for query parameter: method. Value must be one of: string, repository or file") } - -// @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 body object true "for body documentation see the relevant /edge_stacks/create/{method} endpoint" -// @success 200 {object} portainer.EdgeStack -// @failure 500 -// @failure 503 "Edge compute features are disabled" -// @deprecated -// @router /edge_stacks [post] -func deprecatedEdgeStackCreateUrlParser(w http.ResponseWriter, r *http.Request) (string, *httperror.HandlerError) { - method, err := request.RetrieveQueryParameter(r, "method", false) - if err != nil { - return "", httperror.BadRequest("Invalid query parameter: method. Valid values are: file or string", err) - } - - return "/edge_stacks/create/" + method, nil -} diff --git a/api/http/handler/edgestacks/edgestack_status_delete.go b/api/http/handler/edgestacks/edgestack_status_delete.go deleted file mode 100644 index eb54951b6..000000000 --- a/api/http/handler/edgestacks/edgestack_status_delete.go +++ /dev/null @@ -1,87 +0,0 @@ -package edgestacks - -import ( - "errors" - "net/http" - "time" - - portainer "github.com/portainer/portainer/api" - "github.com/portainer/portainer/api/dataservices" - "github.com/portainer/portainer/api/http/middlewares" - httperror "github.com/portainer/portainer/pkg/libhttp/error" - "github.com/portainer/portainer/pkg/libhttp/request" - "github.com/portainer/portainer/pkg/libhttp/response" -) - -// @id EdgeStackStatusDelete -// @summary Delete an EdgeStack status -// @description Authorized only if the request is done by an Edge Environment(Endpoint) -// @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 -// @deprecated -// @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 { - return httperror.BadRequest("Invalid stack identifier route variable", err) - } - - endpoint, err := middlewares.FetchEndpoint(r) - if err != nil { - return httperror.InternalServerError("Unable to retrieve a valid endpoint from the handler context", err) - } - - err = handler.requestBouncer.AuthorizedEdgeEndpointOperation(r, endpoint) - if err != nil { - return httperror.Forbidden("Permission denied to access environment", err) - } - - var stack *portainer.EdgeStack - err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error { - stack, err = handler.deleteEdgeStackStatus(tx, portainer.EdgeStackID(stackID), endpoint) - return err - }) - if err != nil { - var httpErr *httperror.HandlerError - if errors.As(err, &httpErr) { - return httpErr - } - - return httperror.InternalServerError("Unexpected error", err) - } - - return response.JSON(w, stack) -} - -func (handler *Handler) deleteEdgeStackStatus(tx dataservices.DataStoreTx, stackID portainer.EdgeStackID, endpoint *portainer.Endpoint) (*portainer.EdgeStack, error) { - stack, err := tx.EdgeStack().EdgeStack(stackID) - if err != nil { - return nil, handlerDBErr(err, "Unable to find a stack with the specified identifier inside the database") - } - - environmentStatus, ok := stack.Status[endpoint.ID] - if !ok { - environmentStatus = portainer.EdgeStackStatus{} - } - - environmentStatus.Status = append(environmentStatus.Status, portainer.EdgeStackDeploymentStatus{ - Time: time.Now().Unix(), - Type: portainer.EdgeStackStatusRemoved, - }) - - stack.Status[endpoint.ID] = environmentStatus - - err = tx.EdgeStack().UpdateEdgeStack(stack.ID, stack) - if err != nil { - return nil, httperror.InternalServerError("Unable to persist the stack changes inside the database", err) - } - - return stack, nil -} diff --git a/api/http/handler/edgestacks/edgestack_status_delete_test.go b/api/http/handler/edgestacks/edgestack_status_delete_test.go deleted file mode 100644 index 7a3db1315..000000000 --- a/api/http/handler/edgestacks/edgestack_status_delete_test.go +++ /dev/null @@ -1,30 +0,0 @@ -package edgestacks - -import ( - "fmt" - "net/http" - "net/http/httptest" - "testing" - - portainer "github.com/portainer/portainer/api" -) - -func TestDeleteStatus(t *testing.T) { - handler, _ := setupHandler(t) - - endpoint := createEndpoint(t, handler.DataStore) - edgeStack := createEdgeStack(t, handler.DataStore, endpoint.ID) - - req, err := http.NewRequest(http.MethodDelete, fmt.Sprintf("/edge_stacks/%d/status/%d", edgeStack.ID, endpoint.ID), nil) - if err != nil { - t.Fatal("request error:", err) - } - - req.Header.Set(portainer.PortainerAgentEdgeIDHeader, endpoint.EdgeID) - rec := httptest.NewRecorder() - handler.ServeHTTP(rec, req) - - if rec.Code != http.StatusOK { - t.Fatalf("expected a %d response, found: %d", http.StatusOK, rec.Code) - } -} diff --git a/api/http/handler/edgestacks/handler.go b/api/http/handler/edgestacks/handler.go index 290524cb0..9fa90776f 100644 --- a/api/http/handler/edgestacks/handler.go +++ b/api/http/handler/edgestacks/handler.go @@ -37,8 +37,6 @@ func NewHandler(bouncer security.BouncerService, dataStore dataservices.DataStor 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(middlewares.Deprecated(h, deprecatedEdgeStackCreateUrlParser)))).Methods(http.MethodPost) // Deprecated h.Handle("/edge_stacks", bouncer.AdminAccess(bouncer.EdgeComputeOperation(httperror.LoggerHandler(h.edgeStackList)))).Methods(http.MethodGet) h.Handle("/edge_stacks/{id}", @@ -55,8 +53,6 @@ func NewHandler(bouncer security.BouncerService, dataStore dataservices.DataStor edgeStackStatusRouter := h.NewRoute().Subrouter() edgeStackStatusRouter.Use(middlewares.WithEndpoint(h.DataStore.Endpoint(), "endpoint_id")) - edgeStackStatusRouter.PathPrefix("/edge_stacks/{id}/status/{endpoint_id}").Handler(bouncer.PublicAccess(httperror.LoggerHandler(h.edgeStackStatusDelete))).Methods(http.MethodDelete) - return h } diff --git a/api/http/handler/edgetemplates/edgetemplate_list.go b/api/http/handler/edgetemplates/edgetemplate_list.go deleted file mode 100644 index 5b2c7254d..000000000 --- a/api/http/handler/edgetemplates/edgetemplate_list.go +++ /dev/null @@ -1,71 +0,0 @@ -package edgetemplates - -import ( - "net/http" - "slices" - - portainer "github.com/portainer/portainer/api" - "github.com/portainer/portainer/api/http/client" - httperror "github.com/portainer/portainer/pkg/libhttp/error" - "github.com/portainer/portainer/pkg/libhttp/response" - - "github.com/segmentio/encoding/json" -) - -type templateFileFormat struct { - Version string `json:"version"` - Templates []portainer.Template `json:"templates"` -} - -// @id EdgeTemplateList -// @deprecated -// @summary Fetches the list of Edge Templates -// @description **Access policy**: administrator -// @tags edge_templates -// @security ApiKeyAuth -// @security jwt -// @accept json -// @produce json -// @success 200 {array} portainer.Template -// @failure 500 -// @router /edge_templates [get] -func (handler *Handler) edgeTemplateList(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { - settings, err := handler.DataStore.Settings().Settings() - if err != nil { - return httperror.InternalServerError("Unable to retrieve settings from the database", err) - } - - url := portainer.DefaultTemplatesURL - if settings.TemplatesURL != "" { - url = settings.TemplatesURL - } - - var templateData []byte - templateData, err = client.Get(url, 10) - if err != nil { - return httperror.InternalServerError("Unable to retrieve external templates", err) - } - - var templateFile templateFileFormat - - err = json.Unmarshal(templateData, &templateFile) - if err != nil { - return httperror.InternalServerError("Unable to parse template file", err) - } - - // We only support version 3 of the template format - // this is only a temporary fix until we have custom edge templates - if templateFile.Version != "3" { - return httperror.InternalServerError("Unsupported template version", nil) - } - - filteredTemplates := make([]portainer.Template, 0) - - for _, template := range templateFile.Templates { - if slices.Contains(template.Categories, "edge") && slices.Contains([]portainer.TemplateType{portainer.ComposeStackTemplate, portainer.SwarmStackTemplate}, template.Type) { - filteredTemplates = append(filteredTemplates, template) - } - } - - return response.JSON(w, filteredTemplates) -} diff --git a/api/http/handler/edgetemplates/handler.go b/api/http/handler/edgetemplates/handler.go deleted file mode 100644 index d6c98553f..000000000 --- a/api/http/handler/edgetemplates/handler.go +++ /dev/null @@ -1,32 +0,0 @@ -package edgetemplates - -import ( - "net/http" - - "github.com/portainer/portainer/api/dataservices" - "github.com/portainer/portainer/api/http/middlewares" - "github.com/portainer/portainer/api/http/security" - httperror "github.com/portainer/portainer/pkg/libhttp/error" - - "github.com/gorilla/mux" -) - -// Handler is the HTTP handler used to handle edge environment(endpoint) operations. -type Handler struct { - *mux.Router - requestBouncer security.BouncerService - DataStore dataservices.DataStore -} - -// NewHandler creates a handler to manage environment(endpoint) operations. -func NewHandler(bouncer security.BouncerService) *Handler { - h := &Handler{ - Router: mux.NewRouter(), - requestBouncer: bouncer, - } - - h.Handle("/edge_templates", - bouncer.AdminAccess(middlewares.Deprecated(httperror.LoggerHandler(h.edgeTemplateList), func(w http.ResponseWriter, r *http.Request) (string, *httperror.HandlerError) { return "", nil }))).Methods(http.MethodGet) - - return h -} diff --git a/api/http/handler/handler.go b/api/http/handler/handler.go index 4d7973170..4325d9f91 100644 --- a/api/http/handler/handler.go +++ b/api/http/handler/handler.go @@ -11,7 +11,6 @@ import ( "github.com/portainer/portainer/api/http/handler/edgegroups" "github.com/portainer/portainer/api/http/handler/edgejobs" "github.com/portainer/portainer/api/http/handler/edgestacks" - "github.com/portainer/portainer/api/http/handler/edgetemplates" "github.com/portainer/portainer/api/http/handler/endpointedge" "github.com/portainer/portainer/api/http/handler/endpointgroups" "github.com/portainer/portainer/api/http/handler/endpointproxy" @@ -50,7 +49,6 @@ type Handler struct { EdgeGroupsHandler *edgegroups.Handler EdgeJobsHandler *edgejobs.Handler EdgeStacksHandler *edgestacks.Handler - EdgeTemplatesHandler *edgetemplates.Handler EndpointEdgeHandler *endpointedge.Handler EndpointGroupHandler *endpointgroups.Handler EndpointHandler *endpoints.Handler @@ -190,8 +188,6 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.StripPrefix("/api", h.EdgeGroupsHandler).ServeHTTP(w, r) case strings.HasPrefix(r.URL.Path, "/api/edge_jobs"): http.StripPrefix("/api", h.EdgeJobsHandler).ServeHTTP(w, r) - case strings.HasPrefix(r.URL.Path, "/api/edge_templates"): - http.StripPrefix("/api", h.EdgeTemplatesHandler).ServeHTTP(w, r) case strings.HasPrefix(r.URL.Path, "/api/endpoint_groups"): http.StripPrefix("/api", h.EndpointGroupHandler).ServeHTTP(w, r) case strings.HasPrefix(r.URL.Path, "/api/kubernetes"): diff --git a/api/http/handler/helm/handler.go b/api/http/handler/helm/handler.go index 0108f7ef1..fb941940b 100644 --- a/api/http/handler/helm/handler.go +++ b/api/http/handler/helm/handler.go @@ -53,12 +53,6 @@ func NewHandler(bouncer security.BouncerService, dataStore dataservices.DataStor h.Handle("/{id}/kubernetes/helm", httperror.LoggerHandler(h.helmInstall)).Methods(http.MethodPost) - // Deprecated - h.Handle("/{id}/kubernetes/helm/repositories", - httperror.LoggerHandler(h.userGetHelmRepos)).Methods(http.MethodGet) - h.Handle("/{id}/kubernetes/helm/repositories", - httperror.LoggerHandler(h.userCreateHelmRepo)).Methods(http.MethodPost) - return h } diff --git a/api/http/handler/helm/user_helm_repos.go b/api/http/handler/helm/user_helm_repos.go deleted file mode 100644 index 5197f88f9..000000000 --- a/api/http/handler/helm/user_helm_repos.go +++ /dev/null @@ -1,127 +0,0 @@ -package helm - -import ( - "net/http" - "strings" - - portainer "github.com/portainer/portainer/api" - "github.com/portainer/portainer/api/http/security" - "github.com/portainer/portainer/pkg/libhelm" - httperror "github.com/portainer/portainer/pkg/libhttp/error" - "github.com/portainer/portainer/pkg/libhttp/request" - "github.com/portainer/portainer/pkg/libhttp/response" - - "github.com/pkg/errors" -) - -type helmUserRepositoryResponse struct { - GlobalRepository string `json:"GlobalRepository"` - UserRepositories []portainer.HelmUserRepository `json:"UserRepositories"` -} - -type addHelmRepoUrlPayload struct { - URL string `json:"url"` -} - -func (p *addHelmRepoUrlPayload) Validate(_ *http.Request) error { - return libhelm.ValidateHelmRepositoryURL(p.URL, nil) -} - -// @id HelmUserRepositoryCreateDeprecated -// @summary Create a user helm repository -// @description Create a user helm repository. -// @description **Access policy**: authenticated -// @tags helm -// @security ApiKeyAuth -// @security jwt -// @accept json -// @produce json -// @param id path int true "Environment(Endpoint) identifier" -// @param payload body addHelmRepoUrlPayload true "Helm Repository" -// @success 200 {object} portainer.HelmUserRepository "Success" -// @failure 400 "Invalid request" -// @failure 403 "Permission denied" -// @failure 500 "Server error" -// @deprecated -// @router /endpoints/{id}/kubernetes/helm/repositories [post] -func (handler *Handler) userCreateHelmRepo(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { - tokenData, err := security.RetrieveTokenData(r) - if err != nil { - return httperror.InternalServerError("Unable to retrieve user authentication token", err) - } - userID := tokenData.ID - - p := new(addHelmRepoUrlPayload) - err = request.DecodeAndValidateJSONPayload(r, p) - if err != nil { - return httperror.BadRequest("Invalid Helm repository URL", err) - } - - // lowercase, remove trailing slash - p.URL = strings.TrimSuffix(strings.ToLower(p.URL), "/") - - records, err := handler.dataStore.HelmUserRepository().HelmUserRepositoryByUserID(userID) - if err != nil { - return httperror.InternalServerError("Unable to access the DataStore", err) - } - - // check if repo already exists - by doing case insensitive comparison - for _, record := range records { - if strings.EqualFold(record.URL, p.URL) { - errMsg := "Helm repo already registered for user" - return httperror.BadRequest(errMsg, errors.New(errMsg)) - } - } - - record := portainer.HelmUserRepository{ - UserID: userID, - URL: p.URL, - } - - err = handler.dataStore.HelmUserRepository().Create(&record) - if err != nil { - return httperror.InternalServerError("Unable to save a user Helm repository URL", err) - } - - return response.JSON(w, record) -} - -// @id HelmUserRepositoriesListDeprecated -// @summary List a users helm repositories -// @description Inspect a user helm repositories. -// @description **Access policy**: authenticated -// @tags helm -// @security ApiKeyAuth -// @security jwt -// @produce json -// @param id path int true "User identifier" -// @success 200 {object} helmUserRepositoryResponse "Success" -// @failure 400 "Invalid request" -// @failure 403 "Permission denied" -// @failure 500 "Server error" -// @deprecated -// @router /endpoints/{id}/kubernetes/helm/repositories [get] -func (handler *Handler) userGetHelmRepos(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { - tokenData, err := security.RetrieveTokenData(r) - if err != nil { - return httperror.InternalServerError("Unable to retrieve user authentication token", err) - } - userID := tokenData.ID - - settings, err := handler.dataStore.Settings().Settings() - if err != nil { - return httperror.InternalServerError("Unable to retrieve settings from the database", err) - } - - userRepos, err := handler.dataStore.HelmUserRepository().HelmUserRepositoryByUserID(userID) - if err != nil { - return httperror.InternalServerError("Unable to get user Helm repositories", err) - } - - resp := helmUserRepositoryResponse{ - GlobalRepository: settings.HelmRepositoryURL, - UserRepositories: userRepos, - } - - return response.JSON(w, resp) -} diff --git a/api/http/handler/stacks/handler.go b/api/http/handler/stacks/handler.go index 7e5cce040..2ad40a182 100644 --- a/api/http/handler/stacks/handler.go +++ b/api/http/handler/stacks/handler.go @@ -11,7 +11,6 @@ import ( "github.com/portainer/portainer/api/dataservices" dockerclient "github.com/portainer/portainer/api/docker/client" "github.com/portainer/portainer/api/docker/consts" - "github.com/portainer/portainer/api/http/middlewares" "github.com/portainer/portainer/api/http/security" "github.com/portainer/portainer/api/internal/authorization" "github.com/portainer/portainer/api/internal/endpointutils" @@ -62,8 +61,6 @@ func NewHandler(bouncer security.BouncerService) *Handler { h.Handle("/stacks/create/{type}/{method}", bouncer.AuthenticatedAccess(httperror.LoggerHandler(h.stackCreate))).Methods(http.MethodPost) - h.Handle("/stacks", - bouncer.AuthenticatedAccess(middlewares.Deprecated(h, deprecatedStackCreateUrlParser))).Methods(http.MethodPost) // Deprecated h.Handle("/stacks", bouncer.AuthenticatedAccess(httperror.LoggerHandler(h.stackList))).Methods(http.MethodGet) h.Handle("/stacks/{id}", diff --git a/api/http/handler/stacks/stack_create.go b/api/http/handler/stacks/stack_create.go index f45592d09..cb297f9d7 100644 --- a/api/http/handler/stacks/stack_create.go +++ b/api/http/handler/stacks/stack_create.go @@ -1,7 +1,6 @@ package stacks import ( - "fmt" "net/http" portainer "github.com/portainer/portainer/api" @@ -141,53 +140,3 @@ func (handler *Handler) decorateStackResponse(w http.ResponseWriter, stack *port return response.JSON(w, stack) } - -func getStackTypeFromQueryParameter(r *http.Request) (string, error) { - stackType, err := request.RetrieveNumericQueryParameter(r, "type", false) - if err != nil { - return "", err - } - - switch stackType { - case 1: - return "swarm", nil - case 2: - return "standalone", nil - case 3: - return "kubernetes", nil - } - - return "", errors.New(request.ErrInvalidQueryParameter) -} - -// @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 body object true "for body documentation see the relevant /stacks/create/{type}/{method} endpoint" -// @success 200 {object} portainer.Stack -// @failure 400 "Invalid request" -// @failure 500 "Server error" -// @deprecated -// @router /stacks [post] -func deprecatedStackCreateUrlParser(w http.ResponseWriter, r *http.Request) (string, *httperror.HandlerError) { - method, err := request.RetrieveQueryParameter(r, "method", false) - if err != nil { - return "", httperror.BadRequest("Invalid query parameter: method. Valid values are: file or string", err) - } - - stackType, err := getStackTypeFromQueryParameter(r) - if err != nil { - return "", httperror.BadRequest("Invalid query parameter: type", err) - } - - return fmt.Sprintf("/stacks/create/%s/%s", stackType, method), nil -} diff --git a/api/http/handler/system/handler.go b/api/http/handler/system/handler.go index d2e3f5485..4cab43332 100644 --- a/api/http/handler/system/handler.go +++ b/api/http/handler/system/handler.go @@ -59,10 +59,6 @@ func NewHandler(bouncer security.BouncerService, // Deprecated /status endpoint, will be removed in the future. h.Handle("/status", bouncer.PublicAccess(httperror.LoggerHandler(h.statusInspectDeprecated))).Methods(http.MethodGet) - h.Handle("/status/version", - bouncer.AuthenticatedAccess(http.HandlerFunc(h.versionDeprecated))).Methods(http.MethodGet) - h.Handle("/status/nodes", - bouncer.AuthenticatedAccess(httperror.LoggerHandler(h.statusNodesCountDeprecated))).Methods(http.MethodGet) return h } diff --git a/api/http/handler/system/nodes_count.go b/api/http/handler/system/nodes_count.go index 0b9971619..94ab320fa 100644 --- a/api/http/handler/system/nodes_count.go +++ b/api/http/handler/system/nodes_count.go @@ -8,8 +8,6 @@ import ( "github.com/portainer/portainer/api/internal/snapshot" httperror "github.com/portainer/portainer/pkg/libhttp/error" "github.com/portainer/portainer/pkg/libhttp/response" - - "github.com/rs/zerolog/log" ) type nodesCountResponse struct { @@ -44,21 +42,3 @@ func (handler *Handler) systemNodesCount(w http.ResponseWriter, r *http.Request) return response.JSON(w, &nodesCountResponse{Nodes: nodes}) } - -// @id statusNodesCount -// @summary Retrieve the count of nodes -// @deprecated -// @description Deprecated: use the `/system/nodes` endpoint instead. -// @description **Access policy**: authenticated -// @security ApiKeyAuth -// @security jwt -// @tags status -// @produce json -// @success 200 {object} nodesCountResponse "Success" -// @failure 500 "Server error" -// @router /status/nodes [get] -func (handler *Handler) statusNodesCountDeprecated(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { - log.Warn().Msg("The /status/nodes endpoint is deprecated, please use the /system/nodes endpoint instead") - - return handler.systemNodesCount(w, r) -} diff --git a/api/http/handler/system/version.go b/api/http/handler/system/version.go index 50ad2f6af..9d80b88a9 100644 --- a/api/http/handler/system/version.go +++ b/api/http/handler/system/version.go @@ -106,21 +106,3 @@ func HasNewerVersion(currentVersion, latestVersion string) bool { return currentVersionSemver.LessThan(*latestVersionSemver) } - -// @id Version -// @summary Check for portainer updates -// @deprecated -// @description Deprecated: use the `/system/version` endpoint instead. -// @description Check if portainer has an update available -// @description **Access policy**: authenticated -// @security ApiKeyAuth -// @security jwt -// @tags status -// @produce json -// @success 200 {object} versionResponse "Success" -// @router /status/version [get] -func (handler *Handler) versionDeprecated(w http.ResponseWriter, r *http.Request) { - log.Warn().Msg("The /status/version endpoint is deprecated, please use the /system/version endpoint instead") - - handler.version(w, r) -} diff --git a/api/http/handler/templates/handler.go b/api/http/handler/templates/handler.go index e604e8abe..1e7b7f05d 100644 --- a/api/http/handler/templates/handler.go +++ b/api/http/handler/templates/handler.go @@ -29,7 +29,5 @@ func NewHandler(bouncer security.BouncerService) *Handler { bouncer.AuthenticatedAccess(httperror.LoggerHandler(h.templateList))).Methods(http.MethodGet) h.Handle("/templates/{id}/file", bouncer.AuthenticatedAccess(httperror.LoggerHandler(h.templateFile))).Methods(http.MethodPost) - h.Handle("/templates/file", - bouncer.AuthenticatedAccess(httperror.LoggerHandler(h.templateFileOld))).Methods(http.MethodPost) return h } diff --git a/api/http/handler/templates/template_file_old.go b/api/http/handler/templates/template_file_old.go deleted file mode 100644 index 91ac038c5..000000000 --- a/api/http/handler/templates/template_file_old.go +++ /dev/null @@ -1,93 +0,0 @@ -package templates - -import ( - "errors" - "net/http" - - httperror "github.com/portainer/portainer/pkg/libhttp/error" - "github.com/portainer/portainer/pkg/libhttp/request" - "github.com/portainer/portainer/pkg/libhttp/response" - "github.com/rs/zerolog/log" -) - -type filePayload struct { - // URL of a git repository where the file is stored - RepositoryURL string `example:"https://github.com/portainer/portainer-compose" validate:"required"` - // Path to the file inside the git repository - ComposeFilePathInRepository string `example:"./subfolder/docker-compose.yml" validate:"required"` -} - -func (payload *filePayload) Validate(r *http.Request) error { - if len(payload.RepositoryURL) == 0 { - return errors.New("Invalid repository url") - } - - if len(payload.ComposeFilePathInRepository) == 0 { - return errors.New("Invalid file path") - } - - return nil -} - -func (handler *Handler) ifRequestedTemplateExists(payload *filePayload) *httperror.HandlerError { - response, httpErr := handler.fetchTemplates() - if httpErr != nil { - return httpErr - } - - for _, t := range response.Templates { - if t.Repository.URL == payload.RepositoryURL && t.Repository.StackFile == payload.ComposeFilePathInRepository { - return nil - } - } - return httperror.InternalServerError("Invalid template", errors.New("requested template does not exist")) -} - -// @id TemplateFileOld -// @summary Get a template's file -// @deprecated -// @description Get a template's file -// @description **Access policy**: authenticated -// @tags templates -// @security ApiKeyAuth -// @security jwt -// @accept json -// @produce json -// @param body body filePayload true "File details" -// @success 200 {object} fileResponse "Success" -// @failure 400 "Invalid request" -// @failure 500 "Server error" -// @router /templates/file [post] -func (handler *Handler) templateFileOld(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { - log.Warn().Msg("This api is deprecated. Please use /templates/{id}/file instead") - - var payload filePayload - err := request.DecodeAndValidateJSONPayload(r, &payload) - if err != nil { - return httperror.BadRequest("Invalid request payload", err) - } - - if err := handler.ifRequestedTemplateExists(&payload); err != nil { - return err - } - - projectPath, err := handler.FileService.GetTemporaryPath() - if err != nil { - return httperror.InternalServerError("Unable to create temporary folder", err) - } - - defer handler.cleanUp(projectPath) - - err = handler.GitService.CloneRepository(projectPath, payload.RepositoryURL, "", "", "", false) - if err != nil { - return httperror.InternalServerError("Unable to clone git repository", err) - } - - fileContent, err := handler.FileService.GetFileContent(projectPath, payload.ComposeFilePathInRepository) - if err != nil { - return httperror.InternalServerError("Failed loading file content", err) - } - - return response.JSON(w, fileResponse{FileContent: string(fileContent)}) - -} diff --git a/api/http/server.go b/api/http/server.go index ec86e6220..c5bb0d40f 100644 --- a/api/http/server.go +++ b/api/http/server.go @@ -24,7 +24,6 @@ import ( "github.com/portainer/portainer/api/http/handler/edgegroups" "github.com/portainer/portainer/api/http/handler/edgejobs" "github.com/portainer/portainer/api/http/handler/edgestacks" - "github.com/portainer/portainer/api/http/handler/edgetemplates" "github.com/portainer/portainer/api/http/handler/endpointedge" "github.com/portainer/portainer/api/http/handler/endpointgroups" "github.com/portainer/portainer/api/http/handler/endpointproxy" @@ -169,9 +168,6 @@ func (server *Server) Start() error { edgeStacksHandler.GitService = server.GitService edgeStacksHandler.KubernetesDeployer = server.KubernetesDeployer - var edgeTemplatesHandler = edgetemplates.NewHandler(requestBouncer) - edgeTemplatesHandler.DataStore = server.DataStore - var endpointHandler = endpoints.NewHandler(requestBouncer) endpointHandler.DataStore = server.DataStore endpointHandler.FileService = server.FileService @@ -306,7 +302,6 @@ func (server *Server) Start() error { EdgeGroupsHandler: edgeGroupsHandler, EdgeJobsHandler: edgeJobsHandler, EdgeStacksHandler: edgeStacksHandler, - EdgeTemplatesHandler: edgeTemplatesHandler, EndpointGroupHandler: endpointGroupHandler, EndpointHandler: endpointHandler, EndpointHelmHandler: endpointHelmHandler, diff --git a/app/constants.ts b/app/constants.ts index 8a8e687d2..e61172d27 100644 --- a/app/constants.ts +++ b/app/constants.ts @@ -5,7 +5,6 @@ export const API_ENDPOINT_CUSTOM_TEMPLATES = 'api/custom_templates'; export const API_ENDPOINT_EDGE_GROUPS = 'api/edge_groups'; export const API_ENDPOINT_EDGE_JOBS = 'api/edge_jobs'; export const API_ENDPOINT_EDGE_STACKS = 'api/edge_stacks'; -export const API_ENDPOINT_EDGE_TEMPLATES = 'api/edge_templates'; export const API_ENDPOINT_ENDPOINTS = 'api/endpoints'; export const API_ENDPOINT_ENDPOINT_GROUPS = 'api/endpoint_groups'; export const API_ENDPOINT_KUBERNETES = 'api/kubernetes'; diff --git a/app/ng-constants.ts b/app/ng-constants.ts index 527d42132..87fa45b97 100644 --- a/app/ng-constants.ts +++ b/app/ng-constants.ts @@ -7,7 +7,6 @@ import { API_ENDPOINT_EDGE_GROUPS, API_ENDPOINT_EDGE_JOBS, API_ENDPOINT_EDGE_STACKS, - API_ENDPOINT_EDGE_TEMPLATES, API_ENDPOINT_ENDPOINTS, API_ENDPOINT_ENDPOINT_GROUPS, API_ENDPOINT_KUBERNETES, @@ -42,7 +41,6 @@ export const constantsModule = angular .constant('API_ENDPOINT_EDGE_GROUPS', API_ENDPOINT_EDGE_GROUPS) .constant('API_ENDPOINT_EDGE_JOBS', API_ENDPOINT_EDGE_JOBS) .constant('API_ENDPOINT_EDGE_STACKS', API_ENDPOINT_EDGE_STACKS) - .constant('API_ENDPOINT_EDGE_TEMPLATES', API_ENDPOINT_EDGE_TEMPLATES) .constant('API_ENDPOINT_ENDPOINTS', API_ENDPOINT_ENDPOINTS) .constant('API_ENDPOINT_ENDPOINT_GROUPS', API_ENDPOINT_ENDPOINT_GROUPS) .constant('API_ENDPOINT_KUBERNETES', API_ENDPOINT_KUBERNETES)