diff --git a/api/http/handler/auth/authenticate.go b/api/http/handler/auth/authenticate.go index 7b01b056a..f68d95cb6 100644 --- a/api/http/handler/auth/authenticate.go +++ b/api/http/handler/auth/authenticate.go @@ -54,24 +54,24 @@ func (handler *Handler) authenticate(rw http.ResponseWriter, r *http.Request) *h var payload authenticatePayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } settings, err := handler.DataStore.Settings().Settings() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve settings from the database", err} + return httperror.InternalServerError("Unable to retrieve settings from the database", err) } user, err := handler.DataStore.User().UserByUsername(payload.Username) if err != nil { if !handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve a user with the specified username from the database", err} + return httperror.InternalServerError("Unable to retrieve a user with the specified username from the database", err) } if settings.AuthenticationMethod == portainer.AuthenticationInternal || settings.AuthenticationMethod == portainer.AuthenticationOAuth || (settings.AuthenticationMethod == portainer.AuthenticationLDAP && !settings.LDAPSettings.AutoCreateUsers) { - return &httperror.HandlerError{http.StatusUnprocessableEntity, "Invalid credentials", httperrors.ErrUnauthorized} + return &httperror.HandlerError{StatusCode: http.StatusUnprocessableEntity, Message: "Invalid credentials", Err: httperrors.ErrUnauthorized} } } @@ -80,14 +80,14 @@ func (handler *Handler) authenticate(rw http.ResponseWriter, r *http.Request) *h } if settings.AuthenticationMethod == portainer.AuthenticationOAuth { - return &httperror.HandlerError{http.StatusUnprocessableEntity, "Only initial admin is allowed to login without oauth", httperrors.ErrUnauthorized} + return &httperror.HandlerError{StatusCode: http.StatusUnprocessableEntity, Message: "Only initial admin is allowed to login without oauth", Err: httperrors.ErrUnauthorized} } if settings.AuthenticationMethod == portainer.AuthenticationLDAP { return handler.authenticateLDAP(rw, user, payload.Username, payload.Password, &settings.LDAPSettings) } - return &httperror.HandlerError{http.StatusUnprocessableEntity, "Login method is not supported", httperrors.ErrUnauthorized} + return &httperror.HandlerError{StatusCode: http.StatusUnprocessableEntity, Message: "Login method is not supported", Err: httperrors.ErrUnauthorized} } func isUserInitialAdmin(user *portainer.User) bool { @@ -97,7 +97,7 @@ func isUserInitialAdmin(user *portainer.User) bool { func (handler *Handler) authenticateInternal(w http.ResponseWriter, user *portainer.User, password string) *httperror.HandlerError { err := handler.CryptoService.CompareHashAndData(user.Password, password) if err != nil { - return &httperror.HandlerError{http.StatusUnprocessableEntity, "Invalid credentials", httperrors.ErrUnauthorized} + return &httperror.HandlerError{StatusCode: http.StatusUnprocessableEntity, Message: "Invalid credentials", Err: httperrors.ErrUnauthorized} } forceChangePassword := !handler.passwordStrengthChecker.Check(password) @@ -107,11 +107,7 @@ func (handler *Handler) authenticateInternal(w http.ResponseWriter, user *portai func (handler *Handler) authenticateLDAP(w http.ResponseWriter, user *portainer.User, username, password string, ldapSettings *portainer.LDAPSettings) *httperror.HandlerError { err := handler.LDAPService.AuthenticateUser(username, password, ldapSettings) if err != nil { - return &httperror.HandlerError{ - StatusCode: http.StatusForbidden, - Message: "Only initial admin is allowed to login without oauth", - Err: err, - } + return httperror.Forbidden("Only initial admin is allowed to login without oauth", err) } if user == nil { @@ -123,7 +119,7 @@ func (handler *Handler) authenticateLDAP(w http.ResponseWriter, user *portainer. err = handler.DataStore.User().Create(user) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist user inside the database", err} + return httperror.InternalServerError("Unable to persist user inside the database", err) } } @@ -144,7 +140,7 @@ func (handler *Handler) writeToken(w http.ResponseWriter, user *portainer.User, func (handler *Handler) persistAndWriteToken(w http.ResponseWriter, tokenData *portainer.TokenData) *httperror.HandlerError { token, err := handler.JWTService.GenerateToken(tokenData) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to generate JWT token", Err: err} + return httperror.InternalServerError("Unable to generate JWT token", err) } return response.JSON(w, &authenticateResponse{JWT: token}) diff --git a/api/http/handler/auth/authenticate_oauth.go b/api/http/handler/auth/authenticate_oauth.go index 22cd243a2..e296194d3 100644 --- a/api/http/handler/auth/authenticate_oauth.go +++ b/api/http/handler/auth/authenticate_oauth.go @@ -57,31 +57,31 @@ func (handler *Handler) validateOAuth(w http.ResponseWriter, r *http.Request) *h var payload oauthPayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } settings, err := handler.DataStore.Settings().Settings() if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve settings from the database", Err: err} + return httperror.InternalServerError("Unable to retrieve settings from the database", err) } if settings.AuthenticationMethod != portainer.AuthenticationOAuth { - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "OAuth authentication is not enabled", Err: errors.New("OAuth authentication is not enabled")} + return httperror.Forbidden("OAuth authentication is not enabled", errors.New("OAuth authentication is not enabled")) } username, err := handler.authenticateOAuth(payload.Code, &settings.OAuthSettings) if err != nil { log.Printf("[DEBUG] - OAuth authentication error: %s", err) - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to authenticate through OAuth", Err: httperrors.ErrUnauthorized} + return httperror.InternalServerError("Unable to authenticate through OAuth", httperrors.ErrUnauthorized) } user, err := handler.DataStore.User().UserByUsername(username) if err != nil && !handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve a user with the specified username from the database", Err: err} + return httperror.InternalServerError("Unable to retrieve a user with the specified username from the database", err) } if user == nil && !settings.OAuthSettings.OAuthAutoCreateUsers { - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "Account not created beforehand in Portainer and automatic user provisioning not enabled", Err: httperrors.ErrUnauthorized} + return httperror.Forbidden("Account not created beforehand in Portainer and automatic user provisioning not enabled", httperrors.ErrUnauthorized) } if user == nil { @@ -92,7 +92,7 @@ func (handler *Handler) validateOAuth(w http.ResponseWriter, r *http.Request) *h err = handler.DataStore.User().Create(user) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to persist user inside the database", Err: err} + return httperror.InternalServerError("Unable to persist user inside the database", err) } if settings.OAuthSettings.DefaultTeamID != 0 { @@ -104,7 +104,7 @@ func (handler *Handler) validateOAuth(w http.ResponseWriter, r *http.Request) *h err = handler.DataStore.TeamMembership().Create(membership) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to persist team membership inside the database", Err: err} + return httperror.InternalServerError("Unable to persist team membership inside the database", err) } } diff --git a/api/http/handler/auth/logout.go b/api/http/handler/auth/logout.go index 6e4624725..ec3e0b9ac 100644 --- a/api/http/handler/auth/logout.go +++ b/api/http/handler/auth/logout.go @@ -20,7 +20,7 @@ import ( func (handler *Handler) logout(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { tokenData, err := security.RetrieveTokenData(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user details from authentication token", err} + return httperror.InternalServerError("Unable to retrieve user details from authentication token", err) } handler.KubernetesTokenCacheManager.RemoveUserFromCache(int(tokenData.ID)) diff --git a/api/http/handler/backup/backup.go b/api/http/handler/backup/backup.go index c9ac37443..49d5aac9c 100644 --- a/api/http/handler/backup/backup.go +++ b/api/http/handler/backup/backup.go @@ -39,12 +39,12 @@ func (h *Handler) backup(w http.ResponseWriter, r *http.Request) *httperror.Hand var payload backupPayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } archivePath, err := operations.CreateBackupArchive(payload.Password, h.gate, h.dataStore, h.filestorePath) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Failed to create backup", Err: err} + return httperror.InternalServerError("Failed to create backup", err) } defer os.RemoveAll(filepath.Dir(archivePath)) diff --git a/api/http/handler/backup/restore.go b/api/http/handler/backup/restore.go index 5e533f934..7728ba4ce 100644 --- a/api/http/handler/backup/restore.go +++ b/api/http/handler/backup/restore.go @@ -31,10 +31,10 @@ type restorePayload struct { func (h *Handler) restore(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { initialized, err := h.adminMonitor.WasInitialized() if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Failed to check system initialization", Err: err} + return httperror.InternalServerError("Failed to check system initialization", err) } if initialized { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Cannot restore already initialized instance", Err: errors.New("system already initialized")} + return httperror.BadRequest("Cannot restore already initialized instance", errors.New("system already initialized")) } h.adminMonitor.Stop() defer h.adminMonitor.Start() @@ -42,13 +42,13 @@ func (h *Handler) restore(w http.ResponseWriter, r *http.Request) *httperror.Han var payload restorePayload err = decodeForm(r, &payload) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } var archiveReader io.Reader = bytes.NewReader(payload.FileContent) err = operations.RestoreArchive(archiveReader, payload.Password, h.filestorePath, h.gate, h.dataStore, h.shutdownTrigger) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Failed to restore the backup", Err: err} + return httperror.InternalServerError("Failed to restore the backup", err) } return nil diff --git a/api/http/handler/customtemplates/customtemplate_create.go b/api/http/handler/customtemplates/customtemplate_create.go index cf42e3948..66d33cbb9 100644 --- a/api/http/handler/customtemplates/customtemplate_create.go +++ b/api/http/handler/customtemplates/customtemplate_create.go @@ -44,42 +44,42 @@ import ( func (handler *Handler) customTemplateCreate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { method, err := request.RetrieveQueryParameter(r, "method", false) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: method", err} + return httperror.BadRequest("Invalid query parameter: method", err) } tokenData, err := security.RetrieveTokenData(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user details from authentication token", err} + return httperror.InternalServerError("Unable to retrieve user details from authentication token", err) } customTemplate, err := handler.createCustomTemplate(method, r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to create custom template", err} + return httperror.InternalServerError("Unable to create custom template", err) } customTemplate.CreatedByUserID = tokenData.ID customTemplates, err := handler.DataStore.CustomTemplate().CustomTemplates() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve custom templates from the database", err} + return httperror.InternalServerError("Unable to retrieve custom templates from the database", err) } for _, existingTemplate := range customTemplates { if existingTemplate.Title == customTemplate.Title { - return &httperror.HandlerError{http.StatusInternalServerError, "Template name must be unique", errors.New("Template name must be unique")} + return httperror.InternalServerError("Template name must be unique", errors.New("Template name must be unique")) } } err = handler.DataStore.CustomTemplate().Create(customTemplate) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to create custom template", err} + return httperror.InternalServerError("Unable to create custom template", err) } resourceControl := authorization.NewPrivateResourceControl(strconv.Itoa(int(customTemplate.ID)), portainer.CustomTemplateResourceControl, tokenData.ID) err = handler.DataStore.ResourceControl().Create(resourceControl) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist resource control inside the database", err} + return httperror.InternalServerError("Unable to persist resource control inside the database", err) } customTemplate.ResourceControl = resourceControl diff --git a/api/http/handler/customtemplates/customtemplate_delete.go b/api/http/handler/customtemplates/customtemplate_delete.go index 6e1e47532..6e15dbfc6 100644 --- a/api/http/handler/customtemplates/customtemplate_delete.go +++ b/api/http/handler/customtemplates/customtemplate_delete.go @@ -29,45 +29,45 @@ import ( func (handler *Handler) customTemplateDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { customTemplateID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid Custom template identifier route variable", err} + return httperror.BadRequest("Invalid Custom template identifier route variable", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } customTemplate, err := handler.DataStore.CustomTemplate().CustomTemplate(portainer.CustomTemplateID(customTemplateID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a custom template with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a custom template with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a custom template with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a custom template with the specified identifier inside the database", err) } resourceControl, err := handler.DataStore.ResourceControl().ResourceControlByResourceIDAndType(strconv.Itoa(customTemplateID), portainer.CustomTemplateResourceControl) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve a resource control associated to the custom template", err} + return httperror.InternalServerError("Unable to retrieve a resource control associated to the custom template", err) } access := userCanEditTemplate(customTemplate, securityContext) if !access { - return &httperror.HandlerError{http.StatusForbidden, "Access denied to resource", httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Access denied to resource", httperrors.ErrResourceAccessDenied) } err = handler.DataStore.CustomTemplate().DeleteCustomTemplate(portainer.CustomTemplateID(customTemplateID)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove the custom template from the database", err} + return httperror.InternalServerError("Unable to remove the custom template from the database", err) } err = handler.FileService.RemoveDirectory(customTemplate.ProjectPath) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove custom template files from disk", err} + return httperror.InternalServerError("Unable to remove custom template files from disk", err) } if resourceControl != nil { err = handler.DataStore.ResourceControl().DeleteResourceControl(resourceControl.ID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove the associated resource control from the database", err} + return httperror.InternalServerError("Unable to remove the associated resource control from the database", err) } } diff --git a/api/http/handler/customtemplates/customtemplate_file.go b/api/http/handler/customtemplates/customtemplate_file.go index fef95c97c..7666bae25 100644 --- a/api/http/handler/customtemplates/customtemplate_file.go +++ b/api/http/handler/customtemplates/customtemplate_file.go @@ -30,19 +30,19 @@ type fileResponse struct { func (handler *Handler) customTemplateFile(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { customTemplateID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid custom template identifier route variable", err} + return httperror.BadRequest("Invalid custom template identifier route variable", err) } customTemplate, err := handler.DataStore.CustomTemplate().CustomTemplate(portainer.CustomTemplateID(customTemplateID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a custom template with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a custom template with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a custom template with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a custom template with the specified identifier inside the database", err) } fileContent, err := handler.FileService.GetFileContent(customTemplate.ProjectPath, customTemplate.EntryPoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve custom template file from disk", err} + return httperror.InternalServerError("Unable to retrieve custom template file from disk", err) } return response.JSON(w, &fileResponse{FileContent: string(fileContent)}) diff --git a/api/http/handler/customtemplates/customtemplate_inspect.go b/api/http/handler/customtemplates/customtemplate_inspect.go index 3392b8692..7d5627f53 100644 --- a/api/http/handler/customtemplates/customtemplate_inspect.go +++ b/api/http/handler/customtemplates/customtemplate_inspect.go @@ -29,29 +29,29 @@ import ( func (handler *Handler) customTemplateInspect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { customTemplateID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid Custom template identifier route variable", err} + return httperror.BadRequest("Invalid Custom template identifier route variable", err) } customTemplate, err := handler.DataStore.CustomTemplate().CustomTemplate(portainer.CustomTemplateID(customTemplateID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a custom template with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a custom template with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a custom template with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a custom template with the specified identifier inside the database", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user info from request context", err} + return httperror.InternalServerError("Unable to retrieve user info from request context", err) } resourceControl, err := handler.DataStore.ResourceControl().ResourceControlByResourceIDAndType(strconv.Itoa(customTemplateID), portainer.CustomTemplateResourceControl) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve a resource control associated to the custom template", err} + return httperror.InternalServerError("Unable to retrieve a resource control associated to the custom template", err) } access := userCanEditTemplate(customTemplate, securityContext) if !access { - return &httperror.HandlerError{http.StatusForbidden, "Access denied to resource", httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Access denied to resource", httperrors.ErrResourceAccessDenied) } if resourceControl != nil { diff --git a/api/http/handler/customtemplates/customtemplate_list.go b/api/http/handler/customtemplates/customtemplate_list.go index 63d1ab05f..0b6f69d99 100644 --- a/api/http/handler/customtemplates/customtemplate_list.go +++ b/api/http/handler/customtemplates/customtemplate_list.go @@ -27,30 +27,30 @@ import ( func (handler *Handler) customTemplateList(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { templateTypes, err := parseTemplateTypes(r) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid Custom template type", err} + return httperror.BadRequest("Invalid Custom template type", err) } customTemplates, err := handler.DataStore.CustomTemplate().CustomTemplates() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve custom templates from the database", err} + return httperror.InternalServerError("Unable to retrieve custom templates from the database", err) } resourceControls, err := handler.DataStore.ResourceControl().ResourceControls() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve resource controls from the database", err} + return httperror.InternalServerError("Unable to retrieve resource controls from the database", err) } customTemplates = authorization.DecorateCustomTemplates(customTemplates, resourceControls) securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } if !securityContext.IsAdmin { user, err := handler.DataStore.User().User(securityContext.UserID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user information from the database", err} + return httperror.InternalServerError("Unable to retrieve user information from the database", err) } userTeamIDs := make([]portainer.TeamID, 0) diff --git a/api/http/handler/customtemplates/customtemplate_update.go b/api/http/handler/customtemplates/customtemplate_update.go index 0a752de4e..7b0a5e750 100644 --- a/api/http/handler/customtemplates/customtemplate_update.go +++ b/api/http/handler/customtemplates/customtemplate_update.go @@ -83,47 +83,47 @@ func (payload *customTemplateUpdatePayload) Validate(r *http.Request) error { func (handler *Handler) customTemplateUpdate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { customTemplateID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid Custom template identifier route variable", err} + return httperror.BadRequest("Invalid Custom template identifier route variable", err) } var payload customTemplateUpdatePayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } customTemplates, err := handler.DataStore.CustomTemplate().CustomTemplates() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve custom templates from the database", err} + return httperror.InternalServerError("Unable to retrieve custom templates from the database", err) } for _, existingTemplate := range customTemplates { if existingTemplate.ID != portainer.CustomTemplateID(customTemplateID) && existingTemplate.Title == payload.Title { - return &httperror.HandlerError{http.StatusInternalServerError, "Template name must be unique", errors.New("Template name must be unique")} + return httperror.InternalServerError("Template name must be unique", errors.New("Template name must be unique")) } } customTemplate, err := handler.DataStore.CustomTemplate().CustomTemplate(portainer.CustomTemplateID(customTemplateID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a custom template with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a custom template with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a custom template with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a custom template with the specified identifier inside the database", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } access := userCanEditTemplate(customTemplate, securityContext) if !access { - return &httperror.HandlerError{http.StatusForbidden, "Access denied to resource", httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Access denied to resource", httperrors.ErrResourceAccessDenied) } templateFolder := strconv.Itoa(customTemplateID) _, err = handler.FileService.StoreCustomTemplateFileFromBytes(templateFolder, customTemplate.EntryPoint, []byte(payload.FileContent)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist updated custom template file on disk", err} + return httperror.InternalServerError("Unable to persist updated custom template file on disk", err) } customTemplate.Title = payload.Title @@ -136,7 +136,7 @@ func (handler *Handler) customTemplateUpdate(w http.ResponseWriter, r *http.Requ err = handler.DataStore.CustomTemplate().UpdateCustomTemplate(customTemplate.ID, customTemplate) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist custom template changes inside the database", err} + return httperror.InternalServerError("Unable to persist custom template changes inside the database", err) } return response.JSON(w, customTemplate) diff --git a/api/http/handler/edgegroups/edgegroup_create.go b/api/http/handler/edgegroups/edgegroup_create.go index 26c2c3836..60ceab258 100644 --- a/api/http/handler/edgegroups/edgegroup_create.go +++ b/api/http/handler/edgegroups/edgegroup_create.go @@ -49,17 +49,17 @@ func (handler *Handler) edgeGroupCreate(w http.ResponseWriter, r *http.Request) var payload edgeGroupCreatePayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } edgeGroups, err := handler.DataStore.EdgeGroup().EdgeGroups() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve Edge groups from the database", err} + return httperror.InternalServerError("Unable to retrieve Edge groups from the database", err) } for _, edgeGroup := range edgeGroups { if edgeGroup.Name == payload.Name { - return &httperror.HandlerError{http.StatusBadRequest, "Edge group name must be unique", errors.New("Edge group name must be unique")} + return httperror.BadRequest("Edge group name must be unique", errors.New("Edge group name must be unique")) } } @@ -78,7 +78,7 @@ func (handler *Handler) edgeGroupCreate(w http.ResponseWriter, r *http.Request) for _, endpointID := range payload.Endpoints { endpoint, err := handler.DataStore.Endpoint().Endpoint(endpointID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve environment from the database", err} + return httperror.InternalServerError("Unable to retrieve environment from the database", err) } if endpoint.Type == portainer.EdgeAgentOnDockerEnvironment || endpoint.Type == portainer.EdgeAgentOnKubernetesEnvironment { @@ -90,7 +90,7 @@ func (handler *Handler) edgeGroupCreate(w http.ResponseWriter, r *http.Request) err = handler.DataStore.EdgeGroup().Create(edgeGroup) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist the Edge group inside the database", err} + return httperror.InternalServerError("Unable to persist the Edge group inside the database", err) } return response.JSON(w, edgeGroup) diff --git a/api/http/handler/edgegroups/edgegroup_delete.go b/api/http/handler/edgegroups/edgegroup_delete.go index 3111b96a9..660f3f0a0 100644 --- a/api/http/handler/edgegroups/edgegroup_delete.go +++ b/api/http/handler/edgegroups/edgegroup_delete.go @@ -24,32 +24,32 @@ import ( func (handler *Handler) edgeGroupDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { edgeGroupID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid Edge group identifier route variable", err} + return httperror.BadRequest("Invalid Edge group identifier route variable", err) } _, err = handler.DataStore.EdgeGroup().EdgeGroup(portainer.EdgeGroupID(edgeGroupID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an Edge group with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an Edge group with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an Edge group with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an Edge group with the specified identifier inside the database", err) } edgeStacks, err := handler.DataStore.EdgeStack().EdgeStacks() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve Edge stacks from the database", err} + return httperror.InternalServerError("Unable to retrieve Edge stacks from the database", err) } for _, edgeStack := range edgeStacks { for _, groupID := range edgeStack.EdgeGroups { if groupID == portainer.EdgeGroupID(edgeGroupID) { - return &httperror.HandlerError{http.StatusForbidden, "Edge group is used by an Edge stack", errors.New("Edge group is used by an Edge stack")} + return httperror.Forbidden("Edge group is used by an Edge stack", errors.New("Edge group is used by an Edge stack")) } } } err = handler.DataStore.EdgeGroup().DeleteEdgeGroup(portainer.EdgeGroupID(edgeGroupID)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove the Edge group from the database", err} + return httperror.InternalServerError("Unable to remove the Edge group from the database", err) } return response.Empty(w) diff --git a/api/http/handler/edgegroups/edgegroup_inspect.go b/api/http/handler/edgegroups/edgegroup_inspect.go index 933d037d3..780313114 100644 --- a/api/http/handler/edgegroups/edgegroup_inspect.go +++ b/api/http/handler/edgegroups/edgegroup_inspect.go @@ -24,20 +24,20 @@ import ( func (handler *Handler) edgeGroupInspect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { edgeGroupID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid Edge group identifier route variable", err} + return httperror.BadRequest("Invalid Edge group identifier route variable", err) } edgeGroup, err := handler.DataStore.EdgeGroup().EdgeGroup(portainer.EdgeGroupID(edgeGroupID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an Edge group with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an Edge group with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an Edge group with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an Edge group with the specified identifier inside the database", err) } if edgeGroup.Dynamic { endpoints, err := handler.getEndpointsByTags(edgeGroup.TagIDs, edgeGroup.PartialMatch) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve environments and environment groups for Edge group", err} + return httperror.InternalServerError("Unable to retrieve environments and environment groups for Edge group", err) } edgeGroup.Endpoints = endpoints diff --git a/api/http/handler/edgegroups/edgegroup_list.go b/api/http/handler/edgegroups/edgegroup_list.go index 270c07356..295c8dee9 100644 --- a/api/http/handler/edgegroups/edgegroup_list.go +++ b/api/http/handler/edgegroups/edgegroup_list.go @@ -30,12 +30,12 @@ type decoratedEdgeGroup struct { func (handler *Handler) edgeGroupList(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { edgeGroups, err := handler.DataStore.EdgeGroup().EdgeGroups() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve Edge groups from the database", err} + return httperror.InternalServerError("Unable to retrieve Edge groups from the database", err) } edgeStacks, err := handler.DataStore.EdgeStack().EdgeStacks() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve Edge stacks from the database", err} + return httperror.InternalServerError("Unable to retrieve Edge stacks from the database", err) } usedEdgeGroups := make(map[portainer.EdgeGroupID]bool) @@ -55,7 +55,7 @@ func (handler *Handler) edgeGroupList(w http.ResponseWriter, r *http.Request) *h if edgeGroup.Dynamic { endpointIDs, err := handler.getEndpointsByTags(edgeGroup.TagIDs, edgeGroup.PartialMatch) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve environments and environment groups for Edge group", err} + return httperror.InternalServerError("Unable to retrieve environments and environment groups for Edge group", err) } edgeGroup.Endpoints = endpointIDs @@ -63,7 +63,7 @@ func (handler *Handler) edgeGroupList(w http.ResponseWriter, r *http.Request) *h endpointTypes, err := getEndpointTypes(handler.DataStore.Endpoint(), edgeGroup.Endpoints) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve endpoint types for Edge group", err} + return httperror.InternalServerError("Unable to retrieve endpoint types for Edge group", err) } edgeGroup.EndpointTypes = endpointTypes diff --git a/api/http/handler/edgegroups/edgegroup_update.go b/api/http/handler/edgegroups/edgegroup_update.go index 8ca3ef187..ed24ed1cd 100644 --- a/api/http/handler/edgegroups/edgegroup_update.go +++ b/api/http/handler/edgegroups/edgegroup_update.go @@ -50,30 +50,30 @@ func (payload *edgeGroupUpdatePayload) Validate(r *http.Request) error { func (handler *Handler) edgeGroupUpdate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { edgeGroupID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid Edge group identifier route variable", err} + return httperror.BadRequest("Invalid Edge group identifier route variable", err) } var payload edgeGroupUpdatePayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } edgeGroup, err := handler.DataStore.EdgeGroup().EdgeGroup(portainer.EdgeGroupID(edgeGroupID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an Edge group with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an Edge group with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an Edge group with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an Edge group with the specified identifier inside the database", err) } if payload.Name != "" { edgeGroups, err := handler.DataStore.EdgeGroup().EdgeGroups() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve Edge groups from the database", err} + return httperror.InternalServerError("Unable to retrieve Edge groups from the database", err) } for _, edgeGroup := range edgeGroups { if edgeGroup.Name == payload.Name && edgeGroup.ID != portainer.EdgeGroupID(edgeGroupID) { - return &httperror.HandlerError{http.StatusBadRequest, "Edge group name must be unique", errors.New("Edge group name must be unique")} + return httperror.BadRequest("Edge group name must be unique", errors.New("Edge group name must be unique")) } } @@ -81,12 +81,12 @@ func (handler *Handler) edgeGroupUpdate(w http.ResponseWriter, r *http.Request) } endpoints, err := handler.DataStore.Endpoint().Endpoints() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve environments from database", err} + return httperror.InternalServerError("Unable to retrieve environments from database", err) } endpointGroups, err := handler.DataStore.EndpointGroup().EndpointGroups() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve environment groups from database", err} + return httperror.InternalServerError("Unable to retrieve environment groups from database", err) } oldRelatedEndpoints := edge.EdgeGroupRelatedEndpoints(edgeGroup, endpoints, endpointGroups) @@ -99,7 +99,7 @@ func (handler *Handler) edgeGroupUpdate(w http.ResponseWriter, r *http.Request) for _, endpointID := range payload.Endpoints { endpoint, err := handler.DataStore.Endpoint().Endpoint(endpointID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve environment from the database", err} + return httperror.InternalServerError("Unable to retrieve environment from the database", err) } if endpoint.Type == portainer.EdgeAgentOnDockerEnvironment || endpoint.Type == portainer.EdgeAgentOnKubernetesEnvironment { @@ -115,7 +115,7 @@ func (handler *Handler) edgeGroupUpdate(w http.ResponseWriter, r *http.Request) err = handler.DataStore.EdgeGroup().UpdateEdgeGroup(edgeGroup.ID, edgeGroup) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist Edge group changes inside the database", err} + return httperror.InternalServerError("Unable to persist Edge group changes inside the database", err) } newRelatedEndpoints := edge.EdgeGroupRelatedEndpoints(edgeGroup, endpoints, endpointGroups) @@ -124,7 +124,7 @@ func (handler *Handler) edgeGroupUpdate(w http.ResponseWriter, r *http.Request) for _, endpointID := range endpointsToUpdate { err = handler.updateEndpoint(endpointID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist Environment relation changes inside the database", err} + return httperror.InternalServerError("Unable to persist Environment relation changes inside the database", err) } } diff --git a/api/http/handler/edgejobs/edgejob_create.go b/api/http/handler/edgejobs/edgejob_create.go index 33caf32f0..efac661a2 100644 --- a/api/http/handler/edgejobs/edgejob_create.go +++ b/api/http/handler/edgejobs/edgejob_create.go @@ -31,7 +31,7 @@ import ( func (handler *Handler) edgeJobCreate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { method, err := request.RetrieveQueryParameter(r, "method", false) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: method. Valid values are: file or string", err} + return httperror.BadRequest("Invalid query parameter: method. Valid values are: file or string", err) } switch method { @@ -40,7 +40,7 @@ func (handler *Handler) edgeJobCreate(w http.ResponseWriter, r *http.Request) *h case "file": return handler.createEdgeJobFromFile(w, r) default: - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: method. Valid values are: file or string", errors.New(request.ErrInvalidQueryParameter)} + return httperror.BadRequest("Invalid query parameter: method. Valid values are: file or string", errors.New(request.ErrInvalidQueryParameter)) } } @@ -80,14 +80,14 @@ func (handler *Handler) createEdgeJobFromFileContent(w http.ResponseWriter, r *h var payload edgeJobCreateFromFileContentPayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } edgeJob := handler.createEdgeJobObjectFromFileContentPayload(&payload) err = handler.addAndPersistEdgeJob(edgeJob, []byte(payload.FileContent)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to schedule Edge job", err} + return httperror.InternalServerError("Unable to schedule Edge job", err) } return response.JSON(w, edgeJob) @@ -138,14 +138,14 @@ func (handler *Handler) createEdgeJobFromFile(w http.ResponseWriter, r *http.Req payload := &edgeJobCreateFromFilePayload{} err := payload.Validate(r) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } edgeJob := handler.createEdgeJobObjectFromFilePayload(payload) err = handler.addAndPersistEdgeJob(edgeJob, payload.File) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to schedule Edge job", err} + return httperror.InternalServerError("Unable to schedule Edge job", err) } return response.JSON(w, edgeJob) diff --git a/api/http/handler/edgejobs/edgejob_delete.go b/api/http/handler/edgejobs/edgejob_delete.go index 4397f7105..4084b66f5 100644 --- a/api/http/handler/edgejobs/edgejob_delete.go +++ b/api/http/handler/edgejobs/edgejob_delete.go @@ -25,27 +25,27 @@ import ( func (handler *Handler) edgeJobDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { edgeJobID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid Edge job identifier route variable", err} + return httperror.BadRequest("Invalid Edge job identifier route variable", err) } edgeJob, err := handler.DataStore.EdgeJob().EdgeJob(portainer.EdgeJobID(edgeJobID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an Edge job with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an Edge job with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an Edge job with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an Edge job with the specified identifier inside the database", err) } edgeJobFolder := handler.FileService.GetEdgeJobFolder(strconv.Itoa(edgeJobID)) err = handler.FileService.RemoveDirectory(edgeJobFolder) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove the files associated to the Edge job on the filesystem", err} + return httperror.InternalServerError("Unable to remove the files associated to the Edge job on the filesystem", err) } handler.ReverseTunnelService.RemoveEdgeJob(edgeJob.ID) err = handler.DataStore.EdgeJob().DeleteEdgeJob(edgeJob.ID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove the Edge job from the database", err} + return httperror.InternalServerError("Unable to remove the Edge job from the database", err) } return response.Empty(w) diff --git a/api/http/handler/edgejobs/edgejob_file.go b/api/http/handler/edgejobs/edgejob_file.go index 8141aca0a..0af631e5a 100644 --- a/api/http/handler/edgejobs/edgejob_file.go +++ b/api/http/handler/edgejobs/edgejob_file.go @@ -29,19 +29,19 @@ type edgeJobFileResponse struct { func (handler *Handler) edgeJobFile(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { edgeJobID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid Edge job identifier route variable", err} + return httperror.BadRequest("Invalid Edge job identifier route variable", err) } edgeJob, err := handler.DataStore.EdgeJob().EdgeJob(portainer.EdgeJobID(edgeJobID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an Edge job with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an Edge job with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an Edge job with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an Edge job with the specified identifier inside the database", err) } edgeJobFileContent, err := handler.FileService.GetFileContent(edgeJob.ScriptPath, "") if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve Edge job script file from disk", err} + return httperror.InternalServerError("Unable to retrieve Edge job script file from disk", err) } return response.JSON(w, &edgeJobFileResponse{FileContent: string(edgeJobFileContent)}) diff --git a/api/http/handler/edgejobs/edgejob_inspect.go b/api/http/handler/edgejobs/edgejob_inspect.go index 22a48cb78..aba98d686 100644 --- a/api/http/handler/edgejobs/edgejob_inspect.go +++ b/api/http/handler/edgejobs/edgejob_inspect.go @@ -30,14 +30,14 @@ type edgeJobInspectResponse struct { func (handler *Handler) edgeJobInspect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { edgeJobID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid Edge job identifier route variable", err} + return httperror.BadRequest("Invalid Edge job identifier route variable", err) } edgeJob, err := handler.DataStore.EdgeJob().EdgeJob(portainer.EdgeJobID(edgeJobID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an Edge job with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an Edge job with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an Edge job with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an Edge job with the specified identifier inside the database", err) } endpointIDs := []portainer.EndpointID{} diff --git a/api/http/handler/edgejobs/edgejob_list.go b/api/http/handler/edgejobs/edgejob_list.go index 00f1be8a9..651baac51 100644 --- a/api/http/handler/edgejobs/edgejob_list.go +++ b/api/http/handler/edgejobs/edgejob_list.go @@ -23,7 +23,7 @@ import ( func (handler *Handler) edgeJobList(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { edgeJobs, err := handler.DataStore.EdgeJob().EdgeJobs() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve Edge jobs from the database", err} + return httperror.InternalServerError("Unable to retrieve Edge jobs from the database", err) } return response.JSON(w, edgeJobs) diff --git a/api/http/handler/edgejobs/edgejob_tasklogs_clear.go b/api/http/handler/edgejobs/edgejob_tasklogs_clear.go index 9f73a7462..1a79c0922 100644 --- a/api/http/handler/edgejobs/edgejob_tasklogs_clear.go +++ b/api/http/handler/edgejobs/edgejob_tasklogs_clear.go @@ -27,19 +27,19 @@ import ( func (handler *Handler) edgeJobTasksClear(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { edgeJobID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid Edge job identifier route variable", err} + return httperror.BadRequest("Invalid Edge job identifier route variable", err) } taskID, err := request.RetrieveNumericRouteVariableValue(r, "taskID") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid Task identifier route variable", err} + return httperror.BadRequest("Invalid Task identifier route variable", err) } edgeJob, err := handler.DataStore.EdgeJob().EdgeJob(portainer.EdgeJobID(edgeJobID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an Edge job with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an Edge job with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an Edge job with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an Edge job with the specified identifier inside the database", err) } endpointID := portainer.EndpointID(taskID) @@ -51,14 +51,14 @@ func (handler *Handler) edgeJobTasksClear(w http.ResponseWriter, r *http.Request err = handler.FileService.ClearEdgeJobTaskLogs(strconv.Itoa(edgeJobID), strconv.Itoa(taskID)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to clear log file from disk", err} + return httperror.InternalServerError("Unable to clear log file from disk", err) } handler.ReverseTunnelService.AddEdgeJob(endpointID, edgeJob) err = handler.DataStore.EdgeJob().UpdateEdgeJob(edgeJob.ID, edgeJob) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist Edge job changes in the database", err} + return httperror.InternalServerError("Unable to persist Edge job changes in the database", err) } return response.Empty(w) diff --git a/api/http/handler/edgejobs/edgejob_tasklogs_collect.go b/api/http/handler/edgejobs/edgejob_tasklogs_collect.go index 18fb3c6d5..5b88e5b05 100644 --- a/api/http/handler/edgejobs/edgejob_tasklogs_collect.go +++ b/api/http/handler/edgejobs/edgejob_tasklogs_collect.go @@ -26,19 +26,19 @@ import ( func (handler *Handler) edgeJobTasksCollect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { edgeJobID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid Edge job identifier route variable", err} + return httperror.BadRequest("Invalid Edge job identifier route variable", err) } taskID, err := request.RetrieveNumericRouteVariableValue(r, "taskID") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid Task identifier route variable", err} + return httperror.BadRequest("Invalid Task identifier route variable", err) } edgeJob, err := handler.DataStore.EdgeJob().EdgeJob(portainer.EdgeJobID(edgeJobID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an Edge job with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an Edge job with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an Edge job with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an Edge job with the specified identifier inside the database", err) } endpointID := portainer.EndpointID(taskID) @@ -52,7 +52,7 @@ func (handler *Handler) edgeJobTasksCollect(w http.ResponseWriter, r *http.Reque err = handler.DataStore.EdgeJob().UpdateEdgeJob(edgeJob.ID, edgeJob) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist Edge job changes in the database", err} + return httperror.InternalServerError("Unable to persist Edge job changes in the database", err) } return response.Empty(w) diff --git a/api/http/handler/edgejobs/edgejob_tasklogs_inspect.go b/api/http/handler/edgejobs/edgejob_tasklogs_inspect.go index c801c3d08..4f7cd1ab4 100644 --- a/api/http/handler/edgejobs/edgejob_tasklogs_inspect.go +++ b/api/http/handler/edgejobs/edgejob_tasklogs_inspect.go @@ -30,17 +30,17 @@ type fileResponse struct { func (handler *Handler) edgeJobTaskLogsInspect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { edgeJobID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid Edge job identifier route variable", err} + return httperror.BadRequest("Invalid Edge job identifier route variable", err) } taskID, err := request.RetrieveNumericRouteVariableValue(r, "taskID") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid Task identifier route variable", err} + return httperror.BadRequest("Invalid Task identifier route variable", err) } logFileContent, err := handler.FileService.GetEdgeJobTaskLogFileContent(strconv.Itoa(edgeJobID), strconv.Itoa(taskID)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve log file from disk", err} + return httperror.InternalServerError("Unable to retrieve log file from disk", err) } return response.JSON(w, &fileResponse{FileContent: string(logFileContent)}) diff --git a/api/http/handler/edgejobs/edgejob_tasks_list.go b/api/http/handler/edgejobs/edgejob_tasks_list.go index caefb8806..3057b4e7e 100644 --- a/api/http/handler/edgejobs/edgejob_tasks_list.go +++ b/api/http/handler/edgejobs/edgejob_tasks_list.go @@ -32,14 +32,14 @@ type taskContainer struct { func (handler *Handler) edgeJobTasksList(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { edgeJobID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid Edge job identifier route variable", err} + return httperror.BadRequest("Invalid Edge job identifier route variable", err) } edgeJob, err := handler.DataStore.EdgeJob().EdgeJob(portainer.EdgeJobID(edgeJobID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an Edge job with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an Edge job with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an Edge job with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an Edge job with the specified identifier inside the database", err) } tasks := make([]taskContainer, 0) diff --git a/api/http/handler/edgejobs/edgejob_update.go b/api/http/handler/edgejobs/edgejob_update.go index bb4858875..5932d4cab 100644 --- a/api/http/handler/edgejobs/edgejob_update.go +++ b/api/http/handler/edgejobs/edgejob_update.go @@ -45,30 +45,30 @@ func (payload *edgeJobUpdatePayload) Validate(r *http.Request) error { func (handler *Handler) edgeJobUpdate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { edgeJobID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid Edge job identifier route variable", err} + return httperror.BadRequest("Invalid Edge job identifier route variable", err) } var payload edgeJobUpdatePayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } edgeJob, err := handler.DataStore.EdgeJob().EdgeJob(portainer.EdgeJobID(edgeJobID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an Edge job with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an Edge job with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an Edge job with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an Edge job with the specified identifier inside the database", err) } err = handler.updateEdgeSchedule(edgeJob, &payload) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to update Edge job", err} + return httperror.InternalServerError("Unable to update Edge job", err) } err = handler.DataStore.EdgeJob().UpdateEdgeJob(edgeJob.ID, edgeJob) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist Edge job changes inside the database", err} + return httperror.InternalServerError("Unable to persist Edge job changes inside the database", err) } return response.JSON(w, edgeJob) diff --git a/api/http/handler/edgestacks/edgestack_create.go b/api/http/handler/edgestacks/edgestack_create.go index 9c7344d77..c3208a54c 100644 --- a/api/http/handler/edgestacks/edgestack_create.go +++ b/api/http/handler/edgestacks/edgestack_create.go @@ -36,12 +36,12 @@ import ( func (handler *Handler) edgeStackCreate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { method, err := request.RetrieveQueryParameter(r, "method", false) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: method", err} + return httperror.BadRequest("Invalid query parameter: method", err) } edgeStack, err := handler.createSwarmStack(method, r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to create Edge stack", err} + return httperror.InternalServerError("Unable to create Edge stack", err) } return response.JSON(w, edgeStack) diff --git a/api/http/handler/edgestacks/edgestack_delete.go b/api/http/handler/edgestacks/edgestack_delete.go index 56d1504bd..cc89b105a 100644 --- a/api/http/handler/edgestacks/edgestack_delete.go +++ b/api/http/handler/edgestacks/edgestack_delete.go @@ -25,42 +25,42 @@ import ( func (handler *Handler) edgeStackDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { edgeStackID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid edge stack identifier route variable", err} + return httperror.BadRequest("Invalid edge stack identifier route variable", err) } edgeStack, err := handler.DataStore.EdgeStack().EdgeStack(portainer.EdgeStackID(edgeStackID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an edge stack with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an edge stack with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an edge stack with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an edge stack with the specified identifier inside the database", err) } err = handler.DataStore.EdgeStack().DeleteEdgeStack(portainer.EdgeStackID(edgeStackID)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove the edge stack from the database", err} + return httperror.InternalServerError("Unable to remove the edge stack from the database", err) } relationConfig, err := fetchEndpointRelationsConfig(handler.DataStore) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve environments relations config from database", err} + return httperror.InternalServerError("Unable to retrieve environments relations config from database", err) } relatedEndpointIds, err := edge.EdgeStackRelatedEndpoints(edgeStack.EdgeGroups, relationConfig.endpoints, relationConfig.endpointGroups, relationConfig.edgeGroups) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve edge stack related environments from database", err} + return httperror.InternalServerError("Unable to retrieve edge stack related environments from database", err) } for _, endpointID := range relatedEndpointIds { relation, err := handler.DataStore.EndpointRelation().EndpointRelation(endpointID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find environment relation in database", err} + return httperror.InternalServerError("Unable to find environment relation in database", err) } delete(relation.EdgeStacks, edgeStack.ID) err = handler.DataStore.EndpointRelation().UpdateEndpointRelation(endpointID, relation) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist environment relation in database", err} + return httperror.InternalServerError("Unable to persist environment relation in database", err) } } diff --git a/api/http/handler/edgestacks/edgestack_file.go b/api/http/handler/edgestacks/edgestack_file.go index f8c94b506..732133502 100644 --- a/api/http/handler/edgestacks/edgestack_file.go +++ b/api/http/handler/edgestacks/edgestack_file.go @@ -29,14 +29,14 @@ type stackFileResponse struct { func (handler *Handler) edgeStackFile(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { stackID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid edge stack identifier route variable", err} + return httperror.BadRequest("Invalid edge stack identifier route variable", err) } stack, err := handler.DataStore.EdgeStack().EdgeStack(portainer.EdgeStackID(stackID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an edge stack with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an edge stack with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an edge stack with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an edge stack with the specified identifier inside the database", err) } fileName := stack.EntryPoint @@ -46,7 +46,7 @@ func (handler *Handler) edgeStackFile(w http.ResponseWriter, r *http.Request) *h stackFileContent, err := handler.FileService.GetFileContent(stack.ProjectPath, fileName) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve Compose file from disk", err} + return httperror.InternalServerError("Unable to retrieve Compose file from disk", err) } return response.JSON(w, &stackFileResponse{StackFileContent: string(stackFileContent)}) diff --git a/api/http/handler/edgestacks/edgestack_inspect.go b/api/http/handler/edgestacks/edgestack_inspect.go index e383b3c2b..e74e02cd0 100644 --- a/api/http/handler/edgestacks/edgestack_inspect.go +++ b/api/http/handler/edgestacks/edgestack_inspect.go @@ -25,14 +25,14 @@ import ( func (handler *Handler) edgeStackInspect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { edgeStackID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid edge stack identifier route variable", err} + return httperror.BadRequest("Invalid edge stack identifier route variable", err) } edgeStack, err := handler.DataStore.EdgeStack().EdgeStack(portainer.EdgeStackID(edgeStackID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an edge stack with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an edge stack with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an edge stack with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an edge stack with the specified identifier inside the database", err) } return response.JSON(w, edgeStack) diff --git a/api/http/handler/edgestacks/edgestack_list.go b/api/http/handler/edgestacks/edgestack_list.go index b7355598d..3c9d87b40 100644 --- a/api/http/handler/edgestacks/edgestack_list.go +++ b/api/http/handler/edgestacks/edgestack_list.go @@ -22,7 +22,7 @@ import ( func (handler *Handler) edgeStackList(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { edgeStacks, err := handler.DataStore.EdgeStack().EdgeStacks() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve edge stacks from the database", err} + return httperror.InternalServerError("Unable to retrieve edge stacks from the database", err) } return response.JSON(w, edgeStacks) diff --git a/api/http/handler/edgestacks/edgestack_status_delete.go b/api/http/handler/edgestacks/edgestack_status_delete.go index 8adc245a0..f89f738dc 100644 --- a/api/http/handler/edgestacks/edgestack_status_delete.go +++ b/api/http/handler/edgestacks/edgestack_status_delete.go @@ -11,7 +11,7 @@ import ( ) func (handler *Handler) handlerDBErr(err error, msg string) *httperror.HandlerError { - httpErr := &httperror.HandlerError{http.StatusInternalServerError, msg, err} + httpErr := httperror.InternalServerError(msg, err) if handler.DataStore.IsErrObjectNotFound(err) { httpErr.StatusCode = http.StatusNotFound @@ -35,17 +35,17 @@ func (handler *Handler) handlerDBErr(err error, msg string) *httperror.HandlerEr func (handler *Handler) edgeStackStatusDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { stackID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid stack identifier route variable", err} + return httperror.BadRequest("Invalid stack identifier route variable", err) } endpoint, err := middlewares.FetchEndpoint(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve a valid endpoint from the handler context", err} + 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.HandlerError{http.StatusForbidden, "Permission denied to access environment", err} + return httperror.Forbidden("Permission denied to access environment", err) } stack, err := handler.DataStore.EdgeStack().EdgeStack(portainer.EdgeStackID(stackID)) @@ -57,7 +57,7 @@ func (handler *Handler) edgeStackStatusDelete(w http.ResponseWriter, r *http.Req err = handler.DataStore.EdgeStack().UpdateEdgeStack(stack.ID, stack) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist the stack changes inside the database", err} + return httperror.InternalServerError("Unable to persist the stack changes inside the database", err) } return response.JSON(w, stack) diff --git a/api/http/handler/edgestacks/edgestack_status_update.go b/api/http/handler/edgestacks/edgestack_status_update.go index 41bf05f21..d0f84eaf1 100644 --- a/api/http/handler/edgestacks/edgestack_status_update.go +++ b/api/http/handler/edgestacks/edgestack_status_update.go @@ -46,32 +46,32 @@ func (payload *updateStatusPayload) Validate(r *http.Request) error { func (handler *Handler) edgeStackStatusUpdate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { stackID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid stack identifier route variable", err} + return httperror.BadRequest("Invalid stack identifier route variable", err) } stack, err := handler.DataStore.EdgeStack().EdgeStack(portainer.EdgeStackID(stackID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a stack with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a stack with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a stack with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a stack with the specified identifier inside the database", err) } var payload updateStatusPayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(*payload.EndpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } err = handler.requestBouncer.AuthorizedEdgeEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access environment", err} + return httperror.Forbidden("Permission denied to access environment", err) } stack.Status[*payload.EndpointID] = portainer.EdgeStackStatus{ @@ -82,7 +82,7 @@ func (handler *Handler) edgeStackStatusUpdate(w http.ResponseWriter, r *http.Req err = handler.DataStore.EdgeStack().UpdateEdgeStack(stack.ID, stack) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist the stack changes inside the database", err} + return httperror.InternalServerError("Unable to persist the stack changes inside the database", err) } return response.JSON(w, stack) diff --git a/api/http/handler/edgestacks/edgestack_update.go b/api/http/handler/edgestacks/edgestack_update.go index 0fc7f4ad7..5d45d7a75 100644 --- a/api/http/handler/edgestacks/edgestack_update.go +++ b/api/http/handler/edgestacks/edgestack_update.go @@ -49,36 +49,36 @@ func (payload *updateEdgeStackPayload) Validate(r *http.Request) error { func (handler *Handler) edgeStackUpdate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { stackID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid stack identifier route variable", err} + return httperror.BadRequest("Invalid stack identifier route variable", err) } stack, err := handler.DataStore.EdgeStack().EdgeStack(portainer.EdgeStackID(stackID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a stack with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a stack with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a stack with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a stack with the specified identifier inside the database", err) } var payload updateEdgeStackPayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } relationConfig, err := fetchEndpointRelationsConfig(handler.DataStore) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve environments relations config from database", err} + return httperror.InternalServerError("Unable to retrieve environments relations config from database", err) } relatedEndpointIds, err := edge.EdgeStackRelatedEndpoints(stack.EdgeGroups, relationConfig.endpoints, relationConfig.endpointGroups, relationConfig.edgeGroups) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve edge stack related environments from database", err} + return httperror.InternalServerError("Unable to retrieve edge stack related environments from database", err) } if payload.EdgeGroups != nil { newRelated, err := edge.EdgeStackRelatedEndpoints(payload.EdgeGroups, relationConfig.endpoints, relationConfig.endpointGroups, relationConfig.edgeGroups) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve edge stack related environments from database", err} + return httperror.InternalServerError("Unable to retrieve edge stack related environments from database", err) } oldRelatedSet := endpointutils.EndpointSet(relatedEndpointIds) @@ -94,14 +94,14 @@ func (handler *Handler) edgeStackUpdate(w http.ResponseWriter, r *http.Request) for endpointID := range endpointsToRemove { relation, err := handler.DataStore.EndpointRelation().EndpointRelation(endpointID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find environment relation in database", err} + return httperror.InternalServerError("Unable to find environment relation in database", err) } delete(relation.EdgeStacks, stack.ID) err = handler.DataStore.EndpointRelation().UpdateEndpointRelation(endpointID, relation) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist environment relation in database", err} + return httperror.InternalServerError("Unable to persist environment relation in database", err) } } @@ -115,14 +115,14 @@ func (handler *Handler) edgeStackUpdate(w http.ResponseWriter, r *http.Request) for endpointID := range endpointsToAdd { relation, err := handler.DataStore.EndpointRelation().EndpointRelation(endpointID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find environment relation in database", err} + return httperror.InternalServerError("Unable to find environment relation in database", err) } relation.EdgeStacks[stack.ID] = true err = handler.DataStore.EndpointRelation().UpdateEndpointRelation(endpointID, relation) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist environment relation in database", err} + return httperror.InternalServerError("Unable to persist environment relation in database", err) } } @@ -134,7 +134,7 @@ func (handler *Handler) edgeStackUpdate(w http.ResponseWriter, r *http.Request) // deployment type was changed - need to delete the old file err = handler.FileService.RemoveDirectory(stack.ProjectPath) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to clear old files", err} + return httperror.InternalServerError("Unable to clear old files", err) } stack.EntryPoint = "" @@ -150,12 +150,12 @@ func (handler *Handler) edgeStackUpdate(w http.ResponseWriter, r *http.Request) _, err = handler.FileService.StoreEdgeStackFileFromBytes(stackFolder, stack.EntryPoint, []byte(payload.StackFileContent)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist updated Compose file on disk", err} + return httperror.InternalServerError("Unable to persist updated Compose file on disk", err) } err = handler.convertAndStoreKubeManifestIfNeeded(stack, relatedEndpointIds) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to convert and persist updated Kubernetes manifest file on disk", err} + return httperror.InternalServerError("Unable to convert and persist updated Kubernetes manifest file on disk", err) } } else { @@ -165,16 +165,16 @@ func (handler *Handler) edgeStackUpdate(w http.ResponseWriter, r *http.Request) hasDockerEndpoint, err := hasDockerEndpoint(handler.DataStore.Endpoint(), relatedEndpointIds) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to check for existence of docker environment", err} + return httperror.InternalServerError("Unable to check for existence of docker environment", err) } if hasDockerEndpoint { - return &httperror.HandlerError{http.StatusBadRequest, "Edge stack with docker environment cannot be deployed with kubernetes config", err} + return httperror.BadRequest("Edge stack with docker environment cannot be deployed with kubernetes config", err) } _, err = handler.FileService.StoreEdgeStackFileFromBytes(stackFolder, stack.ManifestPath, []byte(payload.StackFileContent)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist updated Compose file on disk", err} + return httperror.InternalServerError("Unable to persist updated Compose file on disk", err) } } @@ -185,7 +185,7 @@ func (handler *Handler) edgeStackUpdate(w http.ResponseWriter, r *http.Request) err = handler.DataStore.EdgeStack().UpdateEdgeStack(stack.ID, stack) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist the stack changes inside the database", err} + return httperror.InternalServerError("Unable to persist the stack changes inside the database", err) } return response.JSON(w, stack) diff --git a/api/http/handler/edgetemplates/edgetemplate_list.go b/api/http/handler/edgetemplates/edgetemplate_list.go index 647f96a41..b36c2a231 100644 --- a/api/http/handler/edgetemplates/edgetemplate_list.go +++ b/api/http/handler/edgetemplates/edgetemplate_list.go @@ -29,7 +29,7 @@ type templateFileFormat struct { func (handler *Handler) edgeTemplateList(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { settings, err := handler.DataStore.Settings().Settings() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve settings from the database", err} + return httperror.InternalServerError("Unable to retrieve settings from the database", err) } url := portainer.DefaultTemplatesURL @@ -40,14 +40,14 @@ func (handler *Handler) edgeTemplateList(w http.ResponseWriter, r *http.Request) var templateData []byte templateData, err = client.Get(url, 10) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve external templates", err} + return httperror.InternalServerError("Unable to retrieve external templates", err) } var templateFile templateFileFormat err = json.Unmarshal(templateData, &templateFile) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to parse template file", err} + return httperror.InternalServerError("Unable to parse template file", err) } filteredTemplates := make([]portainer.Template, 0) diff --git a/api/http/handler/endpointedge/endpoint_edgejob_logs.go b/api/http/handler/endpointedge/endpoint_edgejob_logs.go index 74b120495..73498d710 100644 --- a/api/http/handler/endpointedge/endpoint_edgejob_logs.go +++ b/api/http/handler/endpointedge/endpoint_edgejob_logs.go @@ -39,30 +39,30 @@ func (handler *Handler) endpointEdgeJobsLogs(w http.ResponseWriter, r *http.Requ err = handler.requestBouncer.AuthorizedEdgeEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access environment", err} + return httperror.Forbidden("Permission denied to access environment", err) } edgeJobID, err := request.RetrieveNumericRouteVariableValue(r, "jobID") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid edge job identifier route variable", err} + return httperror.BadRequest("Invalid edge job identifier route variable", err) } var payload logsPayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } edgeJob, err := handler.DataStore.EdgeJob().EdgeJob(portainer.EdgeJobID(edgeJobID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an edge job with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an edge job with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an edge job with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an edge job with the specified identifier inside the database", err) } err = handler.FileService.StoreEdgeJobTaskLogFileFromBytes(strconv.Itoa(edgeJobID), strconv.Itoa(int(endpoint.ID)), []byte(payload.FileContent)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to save task log to the filesystem", err} + return httperror.InternalServerError("Unable to save task log to the filesystem", err) } meta := edgeJob.Endpoints[endpoint.ID] @@ -75,7 +75,7 @@ func (handler *Handler) endpointEdgeJobsLogs(w http.ResponseWriter, r *http.Requ handler.ReverseTunnelService.AddEdgeJob(endpoint.ID, edgeJob) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist edge job changes to the database", err} + return httperror.InternalServerError("Unable to persist edge job changes to the database", err) } return response.JSON(w, nil) diff --git a/api/http/handler/endpointedge/endpoint_edgestack_inspect.go b/api/http/handler/endpointedge/endpoint_edgestack_inspect.go index ccb736ab8..5958f2c4d 100644 --- a/api/http/handler/endpointedge/endpoint_edgestack_inspect.go +++ b/api/http/handler/endpointedge/endpoint_edgestack_inspect.go @@ -37,25 +37,25 @@ func (handler *Handler) endpointEdgeStackInspect(w http.ResponseWriter, r *http. err = handler.requestBouncer.AuthorizedEdgeEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access environment", err} + return httperror.Forbidden("Permission denied to access environment", err) } edgeStackID, err := request.RetrieveNumericRouteVariableValue(r, "stackId") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid edge stack identifier route variable", err} + return httperror.BadRequest("Invalid edge stack identifier route variable", err) } edgeStack, err := handler.DataStore.EdgeStack().EdgeStack(portainer.EdgeStackID(edgeStackID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an edge stack with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an edge stack with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an edge stack with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an edge stack with the specified identifier inside the database", err) } fileName := edgeStack.EntryPoint if endpointutils.IsDockerEndpoint(endpoint) { if fileName == "" { - return &httperror.HandlerError{http.StatusBadRequest, "Docker is not supported by this stack", errors.New("Docker is not supported by this stack")} + return httperror.BadRequest("Docker is not supported by this stack", errors.New("Docker is not supported by this stack")) } } @@ -63,13 +63,13 @@ func (handler *Handler) endpointEdgeStackInspect(w http.ResponseWriter, r *http. fileName = edgeStack.ManifestPath if fileName == "" { - return &httperror.HandlerError{http.StatusBadRequest, "Kubernetes is not supported by this stack", errors.New("Kubernetes is not supported by this stack")} + return httperror.BadRequest("Kubernetes is not supported by this stack", errors.New("Kubernetes is not supported by this stack")) } } stackFileContent, err := handler.FileService.GetFileContent(edgeStack.ProjectPath, fileName) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve Compose file from disk", err} + return httperror.InternalServerError("Unable to retrieve Compose file from disk", err) } return response.JSON(w, configResponse{ diff --git a/api/http/handler/endpointedge/endpoint_edgestatus_inspect.go b/api/http/handler/endpointedge/endpoint_edgestatus_inspect.go index e88b53823..28ae738a9 100644 --- a/api/http/handler/endpointedge/endpoint_edgestatus_inspect.go +++ b/api/http/handler/endpointedge/endpoint_edgestatus_inspect.go @@ -71,7 +71,7 @@ func (handler *Handler) endpointEdgeStatusInspect(w http.ResponseWriter, r *http err = handler.requestBouncer.AuthorizedEdgeEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access environment", err} + return httperror.Forbidden("Permission denied to access environment", err) } if endpoint.EdgeID == "" { @@ -92,14 +92,14 @@ func (handler *Handler) endpointEdgeStatusInspect(w http.ResponseWriter, r *http err = handler.DataStore.Endpoint().UpdateEndpoint(endpoint.ID, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to Unable to persist environment changes inside the database", err} + return httperror.InternalServerError("Unable to Unable to persist environment changes inside the database", err) } checkinInterval := endpoint.EdgeCheckinInterval if endpoint.EdgeCheckinInterval == 0 { settings, err := handler.DataStore.Settings().Settings() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve settings from the database", err} + return httperror.InternalServerError("Unable to retrieve settings from the database", err) } checkinInterval = settings.EdgeAgentCheckinInterval } @@ -167,7 +167,7 @@ func (handler *Handler) buildSchedules(endpointID portainer.EndpointID, tunnel p file, err := handler.FileService.GetFileContent(job.ScriptPath, "") if err != nil { - return nil, &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve Edge job script file", err} + return nil, httperror.InternalServerError("Unable to retrieve Edge job script file", err) } schedule.Script = base64.RawStdEncoding.EncodeToString(file) @@ -179,14 +179,14 @@ func (handler *Handler) buildSchedules(endpointID portainer.EndpointID, tunnel p func (handler *Handler) buildEdgeStacks(endpointID portainer.EndpointID) ([]stackStatusResponse, *httperror.HandlerError) { relation, err := handler.DataStore.EndpointRelation().EndpointRelation(endpointID) if err != nil { - return nil, &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve relation object from the database", err} + return nil, httperror.InternalServerError("Unable to retrieve relation object from the database", err) } edgeStacksStatus := []stackStatusResponse{} for stackID := range relation.EdgeStacks { stack, err := handler.DataStore.EdgeStack().EdgeStack(stackID) if err != nil { - return nil, &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve edge stack from the database", err} + return nil, httperror.InternalServerError("Unable to retrieve edge stack from the database", err) } stackStatus := stackStatusResponse{ diff --git a/api/http/handler/endpointgroups/endpointgroup_create.go b/api/http/handler/endpointgroups/endpointgroup_create.go index dfa243263..cd41498f3 100644 --- a/api/http/handler/endpointgroups/endpointgroup_create.go +++ b/api/http/handler/endpointgroups/endpointgroup_create.go @@ -49,7 +49,7 @@ func (handler *Handler) endpointGroupCreate(w http.ResponseWriter, r *http.Reque var payload endpointGroupCreatePayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } endpointGroup := &portainer.EndpointGroup{ @@ -62,12 +62,12 @@ func (handler *Handler) endpointGroupCreate(w http.ResponseWriter, r *http.Reque err = handler.DataStore.EndpointGroup().Create(endpointGroup) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist the environment group inside the database", err} + return httperror.InternalServerError("Unable to persist the environment group inside the database", err) } endpoints, err := handler.DataStore.Endpoint().Endpoints() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve environments from the database", err} + return httperror.InternalServerError("Unable to retrieve environments from the database", err) } for _, id := range payload.AssociatedEndpoints { @@ -77,12 +77,12 @@ func (handler *Handler) endpointGroupCreate(w http.ResponseWriter, r *http.Reque err := handler.DataStore.Endpoint().UpdateEndpoint(endpoint.ID, &endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to update environment", err} + return httperror.InternalServerError("Unable to update environment", err) } err = handler.updateEndpointRelations(&endpoint, endpointGroup) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist environment relations changes inside the database", err} + return httperror.InternalServerError("Unable to persist environment relations changes inside the database", err) } break @@ -93,14 +93,14 @@ func (handler *Handler) endpointGroupCreate(w http.ResponseWriter, r *http.Reque for _, tagID := range endpointGroup.TagIDs { tag, err := handler.DataStore.Tag().Tag(tagID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve tag from the database", err} + return httperror.InternalServerError("Unable to retrieve tag from the database", err) } tag.EndpointGroups[endpointGroup.ID] = true err = handler.DataStore.Tag().UpdateTag(tagID, tag) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist tag changes inside the database", err} + return httperror.InternalServerError("Unable to persist tag changes inside the database", err) } } diff --git a/api/http/handler/endpointgroups/endpointgroup_delete.go b/api/http/handler/endpointgroups/endpointgroup_delete.go index fc9681e35..feea30c53 100644 --- a/api/http/handler/endpointgroups/endpointgroup_delete.go +++ b/api/http/handler/endpointgroups/endpointgroup_delete.go @@ -26,28 +26,28 @@ import ( func (handler *Handler) endpointGroupDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointGroupID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment group identifier route variable", err} + return httperror.BadRequest("Invalid environment group identifier route variable", err) } if endpointGroupID == 1 { - return &httperror.HandlerError{http.StatusForbidden, "Unable to remove the default 'Unassigned' group", errors.New("Cannot remove the default environment group")} + return httperror.Forbidden("Unable to remove the default 'Unassigned' group", errors.New("Cannot remove the default environment group")) } endpointGroup, err := handler.DataStore.EndpointGroup().EndpointGroup(portainer.EndpointGroupID(endpointGroupID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment group with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment group with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment group with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment group with the specified identifier inside the database", err) } err = handler.DataStore.EndpointGroup().DeleteEndpointGroup(portainer.EndpointGroupID(endpointGroupID)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove the environment group from the database", err} + return httperror.InternalServerError("Unable to remove the environment group from the database", err) } endpoints, err := handler.DataStore.Endpoint().Endpoints() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve environment from the database", err} + return httperror.InternalServerError("Unable to retrieve environment from the database", err) } for _, endpoint := range endpoints { @@ -55,12 +55,12 @@ func (handler *Handler) endpointGroupDelete(w http.ResponseWriter, r *http.Reque endpoint.GroupID = portainer.EndpointGroupID(1) err = handler.DataStore.Endpoint().UpdateEndpoint(endpoint.ID, &endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to update environment", err} + return httperror.InternalServerError("Unable to update environment", err) } err = handler.updateEndpointRelations(&endpoint, nil) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist environment relations changes inside the database", err} + return httperror.InternalServerError("Unable to persist environment relations changes inside the database", err) } } } @@ -68,14 +68,14 @@ func (handler *Handler) endpointGroupDelete(w http.ResponseWriter, r *http.Reque for _, tagID := range endpointGroup.TagIDs { tag, err := handler.DataStore.Tag().Tag(tagID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve tag from the database", err} + return httperror.InternalServerError("Unable to retrieve tag from the database", err) } delete(tag.EndpointGroups, endpointGroup.ID) err = handler.DataStore.Tag().UpdateTag(tagID, tag) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist tag changes inside the database", err} + return httperror.InternalServerError("Unable to persist tag changes inside the database", err) } } diff --git a/api/http/handler/endpointgroups/endpointgroup_endpoint_add.go b/api/http/handler/endpointgroups/endpointgroup_endpoint_add.go index 49ee2607e..3910ede8d 100644 --- a/api/http/handler/endpointgroups/endpointgroup_endpoint_add.go +++ b/api/http/handler/endpointgroups/endpointgroup_endpoint_add.go @@ -26,38 +26,38 @@ import ( func (handler *Handler) endpointGroupAddEndpoint(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointGroupID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment group identifier route variable", err} + return httperror.BadRequest("Invalid environment group identifier route variable", err) } endpointID, err := request.RetrieveNumericRouteVariableValue(r, "endpointId") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment identifier route variable", err} + return httperror.BadRequest("Invalid environment identifier route variable", err) } endpointGroup, err := handler.DataStore.EndpointGroup().EndpointGroup(portainer.EndpointGroupID(endpointGroupID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment group with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment group with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment group with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment group with the specified identifier inside the database", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } endpoint.GroupID = endpointGroup.ID err = handler.DataStore.Endpoint().UpdateEndpoint(endpoint.ID, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist environment changes inside the database", err} + return httperror.InternalServerError("Unable to persist environment changes inside the database", err) } err = handler.updateEndpointRelations(endpoint, endpointGroup) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist environment relations changes inside the database", err} + return httperror.InternalServerError("Unable to persist environment relations changes inside the database", err) } return response.Empty(w) diff --git a/api/http/handler/endpointgroups/endpointgroup_endpoint_delete.go b/api/http/handler/endpointgroups/endpointgroup_endpoint_delete.go index df3de59b2..ff81dd839 100644 --- a/api/http/handler/endpointgroups/endpointgroup_endpoint_delete.go +++ b/api/http/handler/endpointgroups/endpointgroup_endpoint_delete.go @@ -25,38 +25,38 @@ import ( func (handler *Handler) endpointGroupDeleteEndpoint(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointGroupID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment group identifier route variable", err} + return httperror.BadRequest("Invalid environment group identifier route variable", err) } endpointID, err := request.RetrieveNumericRouteVariableValue(r, "endpointId") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment identifier route variable", err} + return httperror.BadRequest("Invalid environment identifier route variable", err) } _, err = handler.DataStore.EndpointGroup().EndpointGroup(portainer.EndpointGroupID(endpointGroupID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment group with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment group with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment group with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment group with the specified identifier inside the database", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } endpoint.GroupID = portainer.EndpointGroupID(1) err = handler.DataStore.Endpoint().UpdateEndpoint(endpoint.ID, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist environment changes inside the database", err} + return httperror.InternalServerError("Unable to persist environment changes inside the database", err) } err = handler.updateEndpointRelations(endpoint, nil) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist environment relations changes inside the database", err} + return httperror.InternalServerError("Unable to persist environment relations changes inside the database", err) } return response.Empty(w) diff --git a/api/http/handler/endpointgroups/endpointgroup_inspect.go b/api/http/handler/endpointgroups/endpointgroup_inspect.go index 10fe7ecbc..df0f19832 100644 --- a/api/http/handler/endpointgroups/endpointgroup_inspect.go +++ b/api/http/handler/endpointgroups/endpointgroup_inspect.go @@ -26,14 +26,14 @@ import ( func (handler *Handler) endpointGroupInspect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointGroupID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment group identifier route variable", err} + return httperror.BadRequest("Invalid environment group identifier route variable", err) } endpointGroup, err := handler.DataStore.EndpointGroup().EndpointGroup(portainer.EndpointGroupID(endpointGroupID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment group with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment group with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment group with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment group with the specified identifier inside the database", err) } return response.JSON(w, endpointGroup) diff --git a/api/http/handler/endpointgroups/endpointgroup_list.go b/api/http/handler/endpointgroups/endpointgroup_list.go index 8088cb0d1..d2c89a13a 100644 --- a/api/http/handler/endpointgroups/endpointgroup_list.go +++ b/api/http/handler/endpointgroups/endpointgroup_list.go @@ -24,12 +24,12 @@ import ( func (handler *Handler) endpointGroupList(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointGroups, err := handler.DataStore.EndpointGroup().EndpointGroups() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve environment groups from the database", err} + return httperror.InternalServerError("Unable to retrieve environment groups from the database", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } endpointGroups = security.FilterEndpointGroups(endpointGroups, securityContext) diff --git a/api/http/handler/endpointgroups/endpointgroup_update.go b/api/http/handler/endpointgroups/endpointgroup_update.go index d9c83752d..8f9578f3c 100644 --- a/api/http/handler/endpointgroups/endpointgroup_update.go +++ b/api/http/handler/endpointgroups/endpointgroup_update.go @@ -45,20 +45,20 @@ func (payload *endpointGroupUpdatePayload) Validate(r *http.Request) error { func (handler *Handler) endpointGroupUpdate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointGroupID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment group identifier route variable", err} + return httperror.BadRequest("Invalid environment group identifier route variable", err) } var payload endpointGroupUpdatePayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } endpointGroup, err := handler.DataStore.EndpointGroup().EndpointGroup(portainer.EndpointGroupID(endpointGroupID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment group with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment group with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment group with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment group with the specified identifier inside the database", err) } if payload.Name != "" { @@ -83,12 +83,12 @@ func (handler *Handler) endpointGroupUpdate(w http.ResponseWriter, r *http.Reque for tagID := range removeTags { tag, err := handler.DataStore.Tag().Tag(tagID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a tag inside the database", err} + return httperror.InternalServerError("Unable to find a tag inside the database", err) } delete(tag.EndpointGroups, endpointGroup.ID) err = handler.DataStore.Tag().UpdateTag(tag.ID, tag) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist tag changes inside the database", err} + return httperror.InternalServerError("Unable to persist tag changes inside the database", err) } } @@ -96,14 +96,14 @@ func (handler *Handler) endpointGroupUpdate(w http.ResponseWriter, r *http.Reque for _, tagID := range payload.TagIDs { tag, err := handler.DataStore.Tag().Tag(tagID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a tag inside the database", err} + return httperror.InternalServerError("Unable to find a tag inside the database", err) } tag.EndpointGroups[endpointGroup.ID] = true err = handler.DataStore.Tag().UpdateTag(tag.ID, tag) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist tag changes inside the database", err} + return httperror.InternalServerError("Unable to persist tag changes inside the database", err) } } } @@ -123,7 +123,7 @@ func (handler *Handler) endpointGroupUpdate(w http.ResponseWriter, r *http.Reque if updateAuthorizations { endpoints, err := handler.DataStore.Endpoint().Endpoints() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve environments from the database", err} + return httperror.InternalServerError("Unable to retrieve environments from the database", err) } for _, endpoint := range endpoints { @@ -131,7 +131,7 @@ func (handler *Handler) endpointGroupUpdate(w http.ResponseWriter, r *http.Reque if endpoint.Type == portainer.KubernetesLocalEnvironment || endpoint.Type == portainer.AgentOnKubernetesEnvironment || endpoint.Type == portainer.EdgeAgentOnKubernetesEnvironment { err = handler.AuthorizationService.CleanNAPWithOverridePolicies(&endpoint, endpointGroup) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to update user authorizations", err} + return httperror.InternalServerError("Unable to update user authorizations", err) } } } @@ -140,13 +140,13 @@ func (handler *Handler) endpointGroupUpdate(w http.ResponseWriter, r *http.Reque err = handler.DataStore.EndpointGroup().UpdateEndpointGroup(endpointGroup.ID, endpointGroup) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist environment group changes inside the database", err} + return httperror.InternalServerError("Unable to persist environment group changes inside the database", err) } if tagsChanged { endpoints, err := handler.DataStore.Endpoint().Endpoints() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve environments from the database", err} + return httperror.InternalServerError("Unable to retrieve environments from the database", err) } @@ -154,7 +154,7 @@ func (handler *Handler) endpointGroupUpdate(w http.ResponseWriter, r *http.Reque if endpoint.GroupID == endpointGroup.ID { err = handler.updateEndpointRelations(&endpoint, endpointGroup) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist environment relations changes inside the database", err} + return httperror.InternalServerError("Unable to persist environment relations changes inside the database", err) } } } diff --git a/api/http/handler/endpointproxy/proxy_azure.go b/api/http/handler/endpointproxy/proxy_azure.go index 3211a1b58..23e1b8c91 100644 --- a/api/http/handler/endpointproxy/proxy_azure.go +++ b/api/http/handler/endpointproxy/proxy_azure.go @@ -13,19 +13,19 @@ import ( func (handler *Handler) proxyRequestsToAzureAPI(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment identifier route variable", err} + return httperror.BadRequest("Invalid environment identifier route variable", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } err = handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access environment", err} + return httperror.Forbidden("Permission denied to access environment", err) } var proxy http.Handler @@ -33,7 +33,7 @@ func (handler *Handler) proxyRequestsToAzureAPI(w http.ResponseWriter, r *http.R if proxy == nil { proxy, err = handler.ProxyManager.CreateAndRegisterEndpointProxy(endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to create proxy", err} + return httperror.InternalServerError("Unable to create proxy", err) } } diff --git a/api/http/handler/endpointproxy/proxy_docker.go b/api/http/handler/endpointproxy/proxy_docker.go index 96a539ddb..2370f0c10 100644 --- a/api/http/handler/endpointproxy/proxy_docker.go +++ b/api/http/handler/endpointproxy/proxy_docker.go @@ -14,29 +14,29 @@ import ( func (handler *Handler) proxyRequestsToDockerAPI(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment identifier route variable", err} + return httperror.BadRequest("Invalid environment identifier route variable", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } err = handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access environment", err} + return httperror.Forbidden("Permission denied to access environment", err) } if endpoint.Type == portainer.EdgeAgentOnDockerEnvironment { if endpoint.EdgeID == "" { - return &httperror.HandlerError{http.StatusInternalServerError, "No Edge agent registered with the environment", errors.New("No agent available")} + return httperror.InternalServerError("No Edge agent registered with the environment", errors.New("No agent available")) } _, err := handler.ReverseTunnelService.GetActiveTunnel(endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to get the active tunnel", err} + return httperror.InternalServerError("Unable to get the active tunnel", err) } } @@ -45,7 +45,7 @@ func (handler *Handler) proxyRequestsToDockerAPI(w http.ResponseWriter, r *http. if proxy == nil { proxy, err = handler.ProxyManager.CreateAndRegisterEndpointProxy(endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to create proxy", err} + return httperror.InternalServerError("Unable to create proxy", err) } } diff --git a/api/http/handler/endpointproxy/proxy_kubernetes.go b/api/http/handler/endpointproxy/proxy_kubernetes.go index b3508b624..ac0bded50 100644 --- a/api/http/handler/endpointproxy/proxy_kubernetes.go +++ b/api/http/handler/endpointproxy/proxy_kubernetes.go @@ -14,29 +14,29 @@ import ( func (handler *Handler) proxyRequestsToKubernetesAPI(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment identifier route variable", err} + return httperror.BadRequest("Invalid environment identifier route variable", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } err = handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access environment", err} + return httperror.Forbidden("Permission denied to access environment", err) } if endpoint.Type == portainer.EdgeAgentOnKubernetesEnvironment { if endpoint.EdgeID == "" { - return &httperror.HandlerError{http.StatusInternalServerError, "No Edge agent registered with the environment", errors.New("No agent available")} + return httperror.InternalServerError("No Edge agent registered with the environment", errors.New("No agent available")) } _, err := handler.ReverseTunnelService.GetActiveTunnel(endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to get the active tunnel", err} + return httperror.InternalServerError("Unable to get the active tunnel", err) } } @@ -45,7 +45,7 @@ func (handler *Handler) proxyRequestsToKubernetesAPI(w http.ResponseWriter, r *h if proxy == nil { proxy, err = handler.ProxyManager.CreateAndRegisterEndpointProxy(endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to create proxy", err} + return httperror.InternalServerError("Unable to create proxy", err) } } diff --git a/api/http/handler/endpoints/endpoint_association_delete.go b/api/http/handler/endpoints/endpoint_association_delete.go index 0329b697a..06140b244 100644 --- a/api/http/handler/endpoints/endpoint_association_delete.go +++ b/api/http/handler/endpoints/endpoint_association_delete.go @@ -31,18 +31,18 @@ import ( func (handler *Handler) endpointAssociationDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment identifier route variable", err} + return httperror.BadRequest("Invalid environment identifier route variable", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } if endpoint.Type != portainer.EdgeAgentOnKubernetesEnvironment && endpoint.Type != portainer.EdgeAgentOnDockerEnvironment { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment type", errors.New("Invalid environment type")} + return httperror.BadRequest("Invalid environment type", errors.New("Invalid environment type")) } endpoint.EdgeID = "" @@ -51,12 +51,12 @@ func (handler *Handler) endpointAssociationDelete(w http.ResponseWriter, r *http endpoint.EdgeKey, err = handler.updateEdgeKey(endpoint.EdgeKey) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Invalid EdgeKey", err} + return httperror.InternalServerError("Invalid EdgeKey", err) } err = handler.DataStore.Endpoint().UpdateEndpoint(portainer.EndpointID(endpointID), endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Failed persisting environment in database", err} + return httperror.InternalServerError("Failed persisting environment in database", err) } handler.ReverseTunnelService.SetTunnelStatusToIdle(endpoint.ID) diff --git a/api/http/handler/endpoints/endpoint_create.go b/api/http/handler/endpoints/endpoint_create.go index 8fe0db2a4..3479299d9 100644 --- a/api/http/handler/endpoints/endpoint_create.go +++ b/api/http/handler/endpoints/endpoint_create.go @@ -191,7 +191,7 @@ func (handler *Handler) endpointCreate(w http.ResponseWriter, r *http.Request) * payload := &endpointCreatePayload{} err := payload.Validate(r) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } isUnique, err := handler.isNameUnique(payload.Name, 0) @@ -210,17 +210,17 @@ func (handler *Handler) endpointCreate(w http.ResponseWriter, r *http.Request) * endpointGroup, err := handler.DataStore.EndpointGroup().EndpointGroup(endpoint.GroupID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment group inside the database", err} + return httperror.InternalServerError("Unable to find an environment group inside the database", err) } edgeGroups, err := handler.DataStore.EdgeGroup().EdgeGroups() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve edge groups from the database", err} + return httperror.InternalServerError("Unable to retrieve edge groups from the database", err) } edgeStacks, err := handler.DataStore.EdgeStack().EdgeStacks() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve edge stacks from the database", err} + return httperror.InternalServerError("Unable to retrieve edge stacks from the database", err) } relationObject := &portainer.EndpointRelation{ @@ -237,7 +237,7 @@ func (handler *Handler) endpointCreate(w http.ResponseWriter, r *http.Request) * err = handler.DataStore.EndpointRelation().Create(relationObject) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist the relation object inside the database", err} + return httperror.InternalServerError("Unable to persist the relation object inside the database", err) } return response.JSON(w, endpoint) @@ -269,7 +269,7 @@ func (handler *Handler) createEndpoint(payload *endpointCreatePayload) (*portain agentPlatform, version, err := agent.GetAgentVersionAndPlatform(payload.URL, tlsConfig) if err != nil { - return nil, &httperror.HandlerError{http.StatusInternalServerError, "Unable to get environment type", err} + return nil, httperror.InternalServerError("Unable to get environment type", err) } agentVersion = version @@ -297,7 +297,7 @@ func (handler *Handler) createAzureEndpoint(payload *endpointCreatePayload) (*po httpClient := client.NewHTTPClient() _, err := httpClient.ExecuteAzureAuthenticationRequest(&credentials) if err != nil { - return nil, &httperror.HandlerError{http.StatusInternalServerError, "Unable to authenticate against Azure", err} + return nil, httperror.InternalServerError("Unable to authenticate against Azure", err) } endpointID := handler.DataStore.Endpoint().GetNextIdentifier() @@ -320,7 +320,7 @@ func (handler *Handler) createAzureEndpoint(payload *endpointCreatePayload) (*po err = handler.saveEndpointAndUpdateAuthorizations(endpoint) if err != nil { - return nil, &httperror.HandlerError{http.StatusInternalServerError, "An error occurred while trying to create the environment", err} + return nil, httperror.InternalServerError("An error occurred while trying to create the environment", err) } return endpoint, nil @@ -360,13 +360,13 @@ func (handler *Handler) createEdgeAgentEndpoint(payload *endpointCreatePayload) settings, err := handler.DataStore.Settings().Settings() if err != nil { - return nil, &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve the settings from the database", err} + return nil, httperror.InternalServerError("Unable to retrieve the settings from the database", err) } if settings.EnforceEdgeID { edgeID, err := uuid.NewV4() if err != nil { - return nil, &httperror.HandlerError{http.StatusInternalServerError, "Cannot generate the Edge ID", err} + return nil, httperror.InternalServerError("Cannot generate the Edge ID", err) } endpoint.EdgeID = edgeID.String() @@ -374,7 +374,7 @@ func (handler *Handler) createEdgeAgentEndpoint(payload *endpointCreatePayload) err = handler.saveEndpointAndUpdateAuthorizations(endpoint) if err != nil { - return nil, &httperror.HandlerError{http.StatusInternalServerError, "An error occured while trying to create the environment", err} + return nil, httperror.InternalServerError("An error occured while trying to create the environment", err) } return endpoint, nil @@ -498,12 +498,12 @@ func (handler *Handler) snapshotAndPersistEndpoint(endpoint *portainer.Endpoint) if strings.Contains(err.Error(), "Invalid request signature") || strings.Contains(err.Error(), "unknown") { err = errors.New("agent already paired with another Portainer instance") } - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to initiate communications with environment", err} + return httperror.InternalServerError("Unable to initiate communications with environment", err) } err = handler.saveEndpointAndUpdateAuthorizations(endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "An error occured while trying to create the environment", err} + return httperror.InternalServerError("An error occured while trying to create the environment", err) } return nil @@ -551,7 +551,7 @@ func (handler *Handler) storeTLSFiles(endpoint *portainer.Endpoint, payload *end if !payload.TLSSkipVerify { caCertPath, err := handler.FileService.StoreTLSFileFromBytes(folder, portainer.TLSFileCA, payload.TLSCACertFile) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist TLS CA certificate file on disk", err} + return httperror.InternalServerError("Unable to persist TLS CA certificate file on disk", err) } endpoint.TLSConfig.TLSCACertPath = caCertPath } @@ -559,13 +559,13 @@ func (handler *Handler) storeTLSFiles(endpoint *portainer.Endpoint, payload *end if !payload.TLSSkipClientVerify { certPath, err := handler.FileService.StoreTLSFileFromBytes(folder, portainer.TLSFileCert, payload.TLSCertFile) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist TLS certificate file on disk", err} + return httperror.InternalServerError("Unable to persist TLS certificate file on disk", err) } endpoint.TLSConfig.TLSCertPath = certPath keyPath, err := handler.FileService.StoreTLSFileFromBytes(folder, portainer.TLSFileKey, payload.TLSKeyFile) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist TLS key file on disk", err} + return httperror.InternalServerError("Unable to persist TLS key file on disk", err) } endpoint.TLSConfig.TLSKeyPath = keyPath } diff --git a/api/http/handler/endpoints/endpoint_create_global_key.go b/api/http/handler/endpoints/endpoint_create_global_key.go index d6ce39a01..be82e9102 100644 --- a/api/http/handler/endpoints/endpoint_create_global_key.go +++ b/api/http/handler/endpoints/endpoint_create_global_key.go @@ -30,7 +30,7 @@ func (handler *Handler) endpointCreateGlobalKey(w http.ResponseWriter, r *http.R endpoints, err := handler.DataStore.Endpoint().Endpoints() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve the endpoints from the database", err} + return httperror.InternalServerError("Unable to retrieve the endpoints from the database", err) } for _, endpoint := range endpoints { @@ -39,5 +39,5 @@ func (handler *Handler) endpointCreateGlobalKey(w http.ResponseWriter, r *http.R } } - return &httperror.HandlerError{http.StatusNotFound, "Unable to find the endpoint in the database", err} + return httperror.NotFound("Unable to find the endpoint in the database", err) } diff --git a/api/http/handler/endpoints/endpoint_delete.go b/api/http/handler/endpoints/endpoint_delete.go index 065df12ec..e271fbbe7 100644 --- a/api/http/handler/endpoints/endpoint_delete.go +++ b/api/http/handler/endpoints/endpoint_delete.go @@ -27,57 +27,57 @@ import ( func (handler *Handler) endpointDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment identifier route variable", err} + return httperror.BadRequest("Invalid environment identifier route variable", err) } if handler.demoService.IsDemoEnvironment(portainer.EndpointID(endpointID)) { - return &httperror.HandlerError{http.StatusForbidden, httperrors.ErrNotAvailableInDemo.Error(), httperrors.ErrNotAvailableInDemo} + return httperror.Forbidden(httperrors.ErrNotAvailableInDemo.Error(), httperrors.ErrNotAvailableInDemo) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } if endpoint.TLSConfig.TLS { folder := strconv.Itoa(endpointID) err = handler.FileService.DeleteTLSFiles(folder) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove TLS files from disk", err} + return httperror.InternalServerError("Unable to remove TLS files from disk", err) } } err = handler.DataStore.Endpoint().DeleteEndpoint(portainer.EndpointID(endpointID)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove environment from the database", err} + return httperror.InternalServerError("Unable to remove environment from the database", err) } handler.ProxyManager.DeleteEndpointProxy(endpoint.ID) err = handler.DataStore.EndpointRelation().DeleteEndpointRelation(endpoint.ID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove environment relation from the database", err} + return httperror.InternalServerError("Unable to remove environment relation from the database", err) } for _, tagID := range endpoint.TagIDs { tag, err := handler.DataStore.Tag().Tag(tagID) if err != nil { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find tag inside the database", err} + return httperror.NotFound("Unable to find tag inside the database", err) } delete(tag.Endpoints, endpoint.ID) err = handler.DataStore.Tag().UpdateTag(tagID, tag) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist tag relation inside the database", err} + return httperror.InternalServerError("Unable to persist tag relation inside the database", err) } } edgeGroups, err := handler.DataStore.EdgeGroup().EdgeGroups() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve edge groups from the database", err} + return httperror.InternalServerError("Unable to retrieve edge groups from the database", err) } for idx := range edgeGroups { @@ -87,14 +87,14 @@ func (handler *Handler) endpointDelete(w http.ResponseWriter, r *http.Request) * edgeGroup.Endpoints = removeElement(edgeGroup.Endpoints, endpointIdx) err = handler.DataStore.EdgeGroup().UpdateEdgeGroup(edgeGroup.ID, edgeGroup) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to update edge group", err} + return httperror.InternalServerError("Unable to update edge group", err) } } } edgeStacks, err := handler.DataStore.EdgeStack().EdgeStacks() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve edge stacks from the database", err} + return httperror.InternalServerError("Unable to retrieve edge stacks from the database", err) } for idx := range edgeStacks { @@ -103,14 +103,14 @@ func (handler *Handler) endpointDelete(w http.ResponseWriter, r *http.Request) * delete(edgeStack.Status, endpoint.ID) err = handler.DataStore.EdgeStack().UpdateEdgeStack(edgeStack.ID, edgeStack) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to update edge stack", err} + return httperror.InternalServerError("Unable to update edge stack", err) } } } registries, err := handler.DataStore.Registry().Registries() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve registries from the database", err} + return httperror.InternalServerError("Unable to retrieve registries from the database", err) } for idx := range registries { @@ -119,7 +119,7 @@ func (handler *Handler) endpointDelete(w http.ResponseWriter, r *http.Request) * delete(registry.RegistryAccesses, endpoint.ID) err = handler.DataStore.Registry().UpdateRegistry(registry.ID, registry) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to update registry accesses", Err: err} + return httperror.InternalServerError("Unable to update registry accesses", err) } } } diff --git a/api/http/handler/endpoints/endpoint_dockerhub_status.go b/api/http/handler/endpoints/endpoint_dockerhub_status.go index 479d0df6e..1c4e05227 100644 --- a/api/http/handler/endpoints/endpoint_dockerhub_status.go +++ b/api/http/handler/endpoints/endpoint_dockerhub_status.go @@ -42,23 +42,23 @@ type dockerhubStatusResponse struct { func (handler *Handler) endpointDockerhubStatus(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment identifier route variable", err} + return httperror.BadRequest("Invalid environment identifier route variable", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } if !endpointutils.IsLocalEndpoint(endpoint) { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment type", errors.New("Invalid environment type")} + return httperror.BadRequest("Invalid environment type", errors.New("Invalid environment type")) } registryID, err := request.RetrieveNumericRouteVariableValue(r, "registryId") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid registry identifier route variable", err} + return httperror.BadRequest("Invalid registry identifier route variable", err) } var registry *portainer.Registry @@ -68,25 +68,25 @@ func (handler *Handler) endpointDockerhubStatus(w http.ResponseWriter, r *http.R } else { registry, err = handler.DataStore.Registry().Registry(portainer.RegistryID(registryID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a registry with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a registry with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a registry with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a registry with the specified identifier inside the database", err) } if registry.Type != portainer.DockerHubRegistry { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid registry type", errors.New("Invalid registry type")} + return httperror.BadRequest("Invalid registry type", errors.New("Invalid registry type")) } } httpClient := client.NewHTTPClient() token, err := getDockerHubToken(httpClient, registry) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve DockerHub token from DockerHub", err} + return httperror.InternalServerError("Unable to retrieve DockerHub token from DockerHub", err) } resp, err := getDockerHubLimits(httpClient, token) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve DockerHub rate limits from DockerHub", err} + return httperror.InternalServerError("Unable to retrieve DockerHub rate limits from DockerHub", err) } return response.JSON(w, resp) diff --git a/api/http/handler/endpoints/endpoint_inspect.go b/api/http/handler/endpoints/endpoint_inspect.go index 55e3ed588..2c7dc27d5 100644 --- a/api/http/handler/endpoints/endpoint_inspect.go +++ b/api/http/handler/endpoints/endpoint_inspect.go @@ -26,19 +26,19 @@ import ( func (handler *Handler) endpointInspect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment identifier route variable", err} + return httperror.BadRequest("Invalid environment identifier route variable", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } err = handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access environment", err} + return httperror.Forbidden("Permission denied to access environment", err) } hideFields(endpoint) diff --git a/api/http/handler/endpoints/endpoint_registries_list.go b/api/http/handler/endpoints/endpoint_registries_list.go index 81b28b099..87eefddb7 100644 --- a/api/http/handler/endpoints/endpoint_registries_list.go +++ b/api/http/handler/endpoints/endpoint_registries_list.go @@ -28,31 +28,31 @@ import ( func (handler *Handler) endpointRegistriesList(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } user, err := handler.DataStore.User().User(securityContext.UserID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user from the database", err} + return httperror.InternalServerError("Unable to retrieve user from the database", err) } endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid environment identifier route variable", Err: err} + return httperror.BadRequest("Invalid environment identifier route variable", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } isAdmin := securityContext.IsAdmin registries, err := handler.DataStore.Registry().Registries() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve registries from the database", err} + return httperror.InternalServerError("Unable to retrieve registries from the database", err) } registries, handleError := handler.filterRegistriesByAccess(r, registries, endpoint, user, securityContext.UserMemberships) @@ -79,16 +79,16 @@ func (handler *Handler) filterKubernetesEndpointRegistries(r *http.Request, regi namespaceParam, _ := request.RetrieveQueryParameter(r, "namespace", true) isAdmin, err := security.IsAdmin(r) if err != nil { - return nil, &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to check user role", Err: err} + return nil, httperror.InternalServerError("Unable to check user role", err) } if namespaceParam != "" { authorized, err := handler.isNamespaceAuthorized(endpoint, namespaceParam, user.ID, memberships, isAdmin) if err != nil { - return nil, &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Unable to check for namespace authorization", Err: err} + return nil, httperror.NotFound("Unable to check for namespace authorization", err) } if !authorized { - return nil, &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "User is not authorized to use namespace", Err: errors.New("user is not authorized to use namespace")} + return nil, httperror.Forbidden("User is not authorized to use namespace", errors.New("user is not authorized to use namespace")) } return filterRegistriesByNamespaces(registries, endpoint.ID, []string{namespaceParam}), nil @@ -154,15 +154,15 @@ func registryAccessPoliciesContainsNamespace(registryAccess portainer.RegistryAc func (handler *Handler) filterKubernetesRegistriesByUserRole(r *http.Request, registries []portainer.Registry, endpoint *portainer.Endpoint, user *portainer.User) ([]portainer.Registry, *httperror.HandlerError) { err := handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) if err == security.ErrAuthorizationRequired { - return nil, &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "User is not authorized", Err: errors.New("missing namespace query parameter")} + return nil, httperror.Forbidden("User is not authorized", errors.New("missing namespace query parameter")) } if err != nil { - return nil, &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve info from request context", Err: err} + return nil, httperror.InternalServerError("Unable to retrieve info from request context", err) } userNamespaces, err := handler.userNamespaces(endpoint, user) if err != nil { - return nil, &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "unable to retrieve user namespaces", Err: err} + return nil, httperror.InternalServerError("unable to retrieve user namespaces", err) } return filterRegistriesByNamespaces(registries, endpoint.ID, userNamespaces), nil diff --git a/api/http/handler/endpoints/endpoint_registry_access.go b/api/http/handler/endpoints/endpoint_registry_access.go index 05af612ef..a3bc01c7e 100644 --- a/api/http/handler/endpoints/endpoint_registry_access.go +++ b/api/http/handler/endpoints/endpoint_registry_access.go @@ -40,46 +40,46 @@ func (payload *registryAccessPayload) Validate(r *http.Request) error { func (handler *Handler) endpointRegistryAccess(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid environment identifier route variable", Err: err} + return httperror.BadRequest("Invalid environment identifier route variable", err) } registryID, err := request.RetrieveNumericRouteVariableValue(r, "registryId") if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid registry identifier route variable", Err: err} + return httperror.BadRequest("Invalid registry identifier route variable", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Unable to find an environment with the specified identifier inside the database", Err: err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to find an environment with the specified identifier inside the database", Err: err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } err = handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access environment", err} + return httperror.Forbidden("Permission denied to access environment", err) } if !securityContext.IsAdmin { - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "User is not authorized", Err: err} + return httperror.Forbidden("User is not authorized", err) } registry, err := handler.DataStore.Registry().Registry(portainer.RegistryID(registryID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Unable to find an environment with the specified identifier inside the database", Err: err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to find an environment with the specified identifier inside the database", Err: err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } var payload registryAccessPayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } if registry.RegistryAccesses == nil { @@ -95,7 +95,7 @@ func (handler *Handler) endpointRegistryAccess(w http.ResponseWriter, r *http.Re if endpoint.Type == portainer.KubernetesLocalEnvironment || endpoint.Type == portainer.AgentOnKubernetesEnvironment || endpoint.Type == portainer.EdgeAgentOnKubernetesEnvironment { err := handler.updateKubeAccess(endpoint, registry, registryAccess.Namespaces, payload.Namespaces) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to update kube access policies", Err: err} + return httperror.InternalServerError("Unable to update kube access policies", err) } registryAccess.Namespaces = payload.Namespaces diff --git a/api/http/handler/endpoints/endpoint_settings_update.go b/api/http/handler/endpoints/endpoint_settings_update.go index 441a66eb4..68713f385 100644 --- a/api/http/handler/endpoints/endpoint_settings_update.go +++ b/api/http/handler/endpoints/endpoint_settings_update.go @@ -53,20 +53,20 @@ func (payload *endpointSettingsUpdatePayload) Validate(r *http.Request) error { func (handler *Handler) endpointSettingsUpdate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment identifier route variable", err} + return httperror.BadRequest("Invalid environment identifier route variable", err) } var payload endpointSettingsUpdatePayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } securitySettings := endpoint.SecuritySettings @@ -111,7 +111,7 @@ func (handler *Handler) endpointSettingsUpdate(w http.ResponseWriter, r *http.Re err = handler.DataStore.Endpoint().UpdateEndpoint(portainer.EndpointID(endpointID), endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Failed persisting environment in database", err} + return httperror.InternalServerError("Failed persisting environment in database", err) } return response.JSON(w, endpoint) diff --git a/api/http/handler/endpoints/endpoint_snapshot.go b/api/http/handler/endpoints/endpoint_snapshot.go index 14f6fe26b..5224c68e9 100644 --- a/api/http/handler/endpoints/endpoint_snapshot.go +++ b/api/http/handler/endpoints/endpoint_snapshot.go @@ -27,25 +27,25 @@ import ( func (handler *Handler) endpointSnapshot(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment identifier route variable", err} + return httperror.BadRequest("Invalid environment identifier route variable", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } if !snapshot.SupportDirectSnapshot(endpoint) { - return &httperror.HandlerError{http.StatusBadRequest, "Snapshots not supported for this environment", errors.New("Snapshots not supported for this environment")} + return httperror.BadRequest("Snapshots not supported for this environment", errors.New("Snapshots not supported for this environment")) } snapshotError := handler.SnapshotService.SnapshotEndpoint(endpoint) latestEndpointReference, err := handler.DataStore.Endpoint().Endpoint(endpoint.ID) if latestEndpointReference == nil { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } latestEndpointReference.Status = portainer.EndpointStatusUp @@ -59,7 +59,7 @@ func (handler *Handler) endpointSnapshot(w http.ResponseWriter, r *http.Request) err = handler.DataStore.Endpoint().UpdateEndpoint(latestEndpointReference.ID, latestEndpointReference) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist environment changes inside the database", err} + return httperror.InternalServerError("Unable to persist environment changes inside the database", err) } return response.Empty(w) diff --git a/api/http/handler/endpoints/endpoint_snapshots.go b/api/http/handler/endpoints/endpoint_snapshots.go index 6432920e4..a3bf807f7 100644 --- a/api/http/handler/endpoints/endpoint_snapshots.go +++ b/api/http/handler/endpoints/endpoint_snapshots.go @@ -23,7 +23,7 @@ import ( func (handler *Handler) endpointSnapshots(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpoints, err := handler.DataStore.Endpoint().Endpoints() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve environments from the database", err} + return httperror.InternalServerError("Unable to retrieve environments from the database", err) } for _, endpoint := range endpoints { @@ -51,7 +51,7 @@ func (handler *Handler) endpointSnapshots(w http.ResponseWriter, r *http.Request err = handler.DataStore.Endpoint().UpdateEndpoint(latestEndpointReference.ID, latestEndpointReference) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist environment changes inside the database", err} + return httperror.InternalServerError("Unable to persist environment changes inside the database", err) } } diff --git a/api/http/handler/endpoints/endpoint_status_inspect.go b/api/http/handler/endpoints/endpoint_status_inspect.go index c166c0199..aebdf90b2 100644 --- a/api/http/handler/endpoints/endpoint_status_inspect.go +++ b/api/http/handler/endpoints/endpoint_status_inspect.go @@ -12,7 +12,7 @@ import ( func (handler *Handler) endpointStatusInspect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment identifier route variable", err} + return httperror.BadRequest("Invalid environment identifier route variable", err) } url := fmt.Sprintf("/api/endpoints/%d/edge/status", endpointID) diff --git a/api/http/handler/endpoints/endpoint_update.go b/api/http/handler/endpoints/endpoint_update.go index 2a52f6f35..b9bce5383 100644 --- a/api/http/handler/endpoints/endpoint_update.go +++ b/api/http/handler/endpoints/endpoint_update.go @@ -73,20 +73,20 @@ func (payload *endpointUpdatePayload) Validate(r *http.Request) error { func (handler *Handler) endpointUpdate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment identifier route variable", err} + return httperror.BadRequest("Invalid environment identifier route variable", err) } var payload endpointUpdatePayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } if payload.Name != nil { @@ -141,13 +141,13 @@ func (handler *Handler) endpointUpdate(w http.ResponseWriter, r *http.Request) * for tagID := range removeTags { tag, err := handler.DataStore.Tag().Tag(tagID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a tag inside the database", err} + return httperror.InternalServerError("Unable to find a tag inside the database", err) } delete(tag.Endpoints, endpoint.ID) err = handler.DataStore.Tag().UpdateTag(tag.ID, tag) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist tag changes inside the database", err} + return httperror.InternalServerError("Unable to persist tag changes inside the database", err) } } @@ -155,14 +155,14 @@ func (handler *Handler) endpointUpdate(w http.ResponseWriter, r *http.Request) * for _, tagID := range payload.TagIDs { tag, err := handler.DataStore.Tag().Tag(tagID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a tag inside the database", err} + return httperror.InternalServerError("Unable to find a tag inside the database", err) } tag.Endpoints[endpoint.ID] = true err = handler.DataStore.Tag().UpdateTag(tag.ID, tag) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist tag changes inside the database", err} + return httperror.InternalServerError("Unable to persist tag changes inside the database", err) } } } @@ -217,7 +217,7 @@ func (handler *Handler) endpointUpdate(w http.ResponseWriter, r *http.Request) * httpClient := client.NewHTTPClient() _, authErr := httpClient.ExecuteAzureAuthenticationRequest(&credentials) if authErr != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to authenticate against Azure", authErr} + return httperror.InternalServerError("Unable to authenticate against Azure", authErr) } endpoint.AzureCredentials = credentials } @@ -261,7 +261,7 @@ func (handler *Handler) endpointUpdate(w http.ResponseWriter, r *http.Request) * endpoint.TLSConfig.TLSKeyPath = "" err = handler.FileService.DeleteTLSFiles(folder) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove TLS files from disk", err} + return httperror.InternalServerError("Unable to remove TLS files from disk", err) } } @@ -275,7 +275,7 @@ func (handler *Handler) endpointUpdate(w http.ResponseWriter, r *http.Request) * handler.ProxyManager.DeleteEndpointProxy(endpoint.ID) _, err = handler.ProxyManager.CreateAndRegisterEndpointProxy(endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to register HTTP proxy for the environment", err} + return httperror.InternalServerError("Unable to register HTTP proxy for the environment", err) } } @@ -283,35 +283,35 @@ func (handler *Handler) endpointUpdate(w http.ResponseWriter, r *http.Request) * if endpoint.Type == portainer.KubernetesLocalEnvironment || endpoint.Type == portainer.AgentOnKubernetesEnvironment || endpoint.Type == portainer.EdgeAgentOnKubernetesEnvironment { err = handler.AuthorizationService.CleanNAPWithOverridePolicies(endpoint, nil) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to update user authorizations", err} + return httperror.InternalServerError("Unable to update user authorizations", err) } } } err = handler.DataStore.Endpoint().UpdateEndpoint(endpoint.ID, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist environment changes inside the database", err} + return httperror.InternalServerError("Unable to persist environment changes inside the database", err) } if (endpoint.Type == portainer.EdgeAgentOnDockerEnvironment || endpoint.Type == portainer.EdgeAgentOnKubernetesEnvironment) && (groupIDChanged || tagsChanged) { relation, err := handler.DataStore.EndpointRelation().EndpointRelation(endpoint.ID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find environment relation inside the database", err} + return httperror.InternalServerError("Unable to find environment relation inside the database", err) } endpointGroup, err := handler.DataStore.EndpointGroup().EndpointGroup(endpoint.GroupID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find environment group inside the database", err} + return httperror.InternalServerError("Unable to find environment group inside the database", err) } edgeGroups, err := handler.DataStore.EdgeGroup().EdgeGroups() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve edge groups from the database", err} + return httperror.InternalServerError("Unable to retrieve edge groups from the database", err) } edgeStacks, err := handler.DataStore.EdgeStack().EdgeStacks() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve edge stacks from the database", err} + return httperror.InternalServerError("Unable to retrieve edge stacks from the database", err) } currentEdgeStackSet := map[portainer.EdgeStackID]bool{} @@ -325,7 +325,7 @@ func (handler *Handler) endpointUpdate(w http.ResponseWriter, r *http.Request) * err = handler.DataStore.EndpointRelation().UpdateEndpointRelation(endpoint.ID, relation) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist environment relation changes inside the database", err} + return httperror.InternalServerError("Unable to persist environment relation changes inside the database", err) } } diff --git a/api/http/handler/helm/handler.go b/api/http/handler/helm/handler.go index bf03642a2..0a2ddc39b 100644 --- a/api/http/handler/helm/handler.go +++ b/api/http/handler/helm/handler.go @@ -87,22 +87,22 @@ func NewTemplateHandler(bouncer requestBouncer, helmPackageManager libhelm.HelmP func (handler *Handler) getHelmClusterAccess(r *http.Request) (*options.KubernetesClusterAccess, *httperror.HandlerError) { endpoint, err := middlewares.FetchEndpoint(r) if err != nil { - return nil, &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment on request context", err} + return nil, httperror.NotFound("Unable to find an environment on request context", err) } tokenData, err := security.RetrieveTokenData(r) if err != nil { - return nil, &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user authentication token", err} + return nil, httperror.InternalServerError("Unable to retrieve user authentication token", err) } bearerToken, err := handler.jwtService.GenerateToken(tokenData) if err != nil { - return nil, &httperror.HandlerError{http.StatusUnauthorized, "Unauthorized", err} + return nil, httperror.Unauthorized("Unauthorized", err) } sslSettings, err := handler.dataStore.SSLSettings().Settings() if err != nil { - return nil, &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve settings from the database", err} + return nil, httperror.InternalServerError("Unable to retrieve settings from the database", err) } hostURL := "localhost" diff --git a/api/http/handler/helm/helm_delete.go b/api/http/handler/helm/helm_delete.go index f1199219e..f779e1cf5 100644 --- a/api/http/handler/helm/helm_delete.go +++ b/api/http/handler/helm/helm_delete.go @@ -28,7 +28,7 @@ import ( func (handler *Handler) helmDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { release, err := request.RetrieveRouteVariableValue(r, "release") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "No release specified", err} + return httperror.BadRequest("No release specified", err) } clusterAccess, httperr := handler.getHelmClusterAccess(r) @@ -48,7 +48,7 @@ func (handler *Handler) helmDelete(w http.ResponseWriter, r *http.Request) *http err = handler.helmPackageManager.Uninstall(uninstallOpts) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Helm returned an error", err} + return httperror.InternalServerError("Helm returned an error", err) } return response.Empty(w) diff --git a/api/http/handler/helm/helm_install.go b/api/http/handler/helm/helm_install.go index 85d84e0fa..248e0659c 100644 --- a/api/http/handler/helm/helm_install.go +++ b/api/http/handler/helm/helm_install.go @@ -53,20 +53,12 @@ func (handler *Handler) helmInstall(w http.ResponseWriter, r *http.Request) *htt var payload installChartPayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{ - StatusCode: http.StatusBadRequest, - Message: "Invalid Helm install payload", - Err: err, - } + return httperror.BadRequest("Invalid Helm install payload", err) } release, err := handler.installChart(r, payload) if err != nil { - return &httperror.HandlerError{ - StatusCode: http.StatusInternalServerError, - Message: "Unable to install a chart", - Err: err, - } + return httperror.InternalServerError("Unable to install a chart", err) } w.WriteHeader(http.StatusCreated) diff --git a/api/http/handler/helm/helm_list.go b/api/http/handler/helm/helm_list.go index 55e92a184..029f55dae 100644 --- a/api/http/handler/helm/helm_list.go +++ b/api/http/handler/helm/helm_list.go @@ -58,7 +58,7 @@ func (handler *Handler) helmList(w http.ResponseWriter, r *http.Request) *httper releases, err := handler.helmPackageManager.List(listOpts) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Helm returned an error", err} + return httperror.InternalServerError("Helm returned an error", err) } return response.JSON(w, releases) diff --git a/api/http/handler/helm/helm_repo_search.go b/api/http/handler/helm/helm_repo_search.go index 3b731a412..24e992832 100644 --- a/api/http/handler/helm/helm_repo_search.go +++ b/api/http/handler/helm/helm_repo_search.go @@ -28,12 +28,12 @@ import ( func (handler *Handler) helmRepoSearch(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { repo := r.URL.Query().Get("repo") if repo == "" { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Bad request", Err: errors.New("missing `repo` query parameter")} + return httperror.BadRequest("Bad request", errors.New("missing `repo` query parameter")) } _, err := url.ParseRequestURI(repo) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Bad request", Err: errors.Wrap(err, fmt.Sprintf("provided URL %q is not valid", repo))} + return httperror.BadRequest("Bad request", errors.Wrap(err, fmt.Sprintf("provided URL %q is not valid", repo))) } searchOpts := options.SearchRepoOptions{ @@ -42,11 +42,7 @@ func (handler *Handler) helmRepoSearch(w http.ResponseWriter, r *http.Request) * result, err := handler.helmPackageManager.SearchRepo(searchOpts) if err != nil { - return &httperror.HandlerError{ - StatusCode: http.StatusInternalServerError, - Message: "Search failed", - Err: err, - } + return httperror.InternalServerError("Search failed", err) } w.Header().Set("Content-Type", "text/plain") diff --git a/api/http/handler/helm/helm_show.go b/api/http/handler/helm/helm_show.go index 797bffa92..51ae3133c 100644 --- a/api/http/handler/helm/helm_show.go +++ b/api/http/handler/helm/helm_show.go @@ -32,16 +32,16 @@ import ( func (handler *Handler) helmShow(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { repo := r.URL.Query().Get("repo") if repo == "" { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Bad request", Err: errors.New("missing `repo` query parameter")} + return httperror.BadRequest("Bad request", errors.New("missing `repo` query parameter")) } _, err := url.ParseRequestURI(repo) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Bad request", Err: errors.Wrap(err, fmt.Sprintf("provided URL %q is not valid", repo))} + return httperror.BadRequest("Bad request", errors.Wrap(err, fmt.Sprintf("provided URL %q is not valid", repo))) } chart := r.URL.Query().Get("chart") if chart == "" { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Bad request", Err: errors.New("missing `chart` query parameter")} + return httperror.BadRequest("Bad request", errors.New("missing `chart` query parameter")) } cmd, err := request.RetrieveRouteVariableValue(r, "command") @@ -57,11 +57,7 @@ func (handler *Handler) helmShow(w http.ResponseWriter, r *http.Request) *httper } result, err := handler.helmPackageManager.Show(showOptions) if err != nil { - return &httperror.HandlerError{ - StatusCode: http.StatusInternalServerError, - Message: "Unable to show chart", - Err: err, - } + return httperror.InternalServerError("Unable to show chart", err) } w.Header().Set("Content-Type", "text/plain") diff --git a/api/http/handler/helm/user_helm_repos.go b/api/http/handler/helm/user_helm_repos.go index 6f8e5b204..ab3a0c5f3 100644 --- a/api/http/handler/helm/user_helm_repos.go +++ b/api/http/handler/helm/user_helm_repos.go @@ -47,32 +47,28 @@ func (p *addHelmRepoUrlPayload) Validate(_ *http.Request) error { func (handler *Handler) userCreateHelmRepo(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { tokenData, err := security.RetrieveTokenData(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user authentication token", err} + return httperror.InternalServerError("Unable to retrieve user authentication token", err) } userID := portainer.UserID(tokenData.ID) p := new(addHelmRepoUrlPayload) err = request.DecodeAndValidateJSONPayload(r, p) if err != nil { - return &httperror.HandlerError{ - StatusCode: http.StatusBadRequest, - Message: "Invalid Helm repository URL", - Err: err, - } + 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.HandlerError{http.StatusInternalServerError, "Unable to access the DataStore", err} + 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.HandlerError{StatusCode: http.StatusBadRequest, Message: errMsg, Err: errors.New(errMsg)} + return httperror.BadRequest(errMsg, errors.New(errMsg)) } } @@ -83,7 +79,7 @@ func (handler *Handler) userCreateHelmRepo(w http.ResponseWriter, r *http.Reques err = handler.dataStore.HelmUserRepository().Create(&record) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to save a user Helm repository URL", err} + return httperror.InternalServerError("Unable to save a user Helm repository URL", err) } return response.JSON(w, record) @@ -106,18 +102,18 @@ func (handler *Handler) userCreateHelmRepo(w http.ResponseWriter, r *http.Reques func (handler *Handler) userGetHelmRepos(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { tokenData, err := security.RetrieveTokenData(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user authentication token", err} + return httperror.InternalServerError("Unable to retrieve user authentication token", err) } userID := portainer.UserID(tokenData.ID) settings, err := handler.dataStore.Settings().Settings() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve settings from the database", err} + return httperror.InternalServerError("Unable to retrieve settings from the database", err) } userRepos, err := handler.dataStore.HelmUserRepository().HelmUserRepositoryByUserID(userID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to get user Helm repositories", err} + return httperror.InternalServerError("Unable to get user Helm repositories", err) } resp := helmUserRepositoryResponse{ diff --git a/api/http/handler/hostmanagement/fdo/configure.go b/api/http/handler/hostmanagement/fdo/configure.go index e207675bd..918832f68 100644 --- a/api/http/handler/hostmanagement/fdo/configure.go +++ b/api/http/handler/hostmanagement/fdo/configure.go @@ -64,7 +64,7 @@ func (handler *Handler) fdoConfigureDevice(w http.ResponseWriter, r *http.Reques guid, err := request.RetrieveRouteVariableValue(r, "guid") if err != nil { logrus.WithError(err).Info("fdoConfigureDevice: request.RetrieveRouteVariableValue()") - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "fdoConfigureDevice: guid not found", Err: err} + return httperror.InternalServerError("fdoConfigureDevice: guid not found", err) } var payload deviceConfigurePayload @@ -72,26 +72,26 @@ func (handler *Handler) fdoConfigureDevice(w http.ResponseWriter, r *http.Reques err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { logrus.WithError(err).Error("Invalid request payload") - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } profile, err := handler.DataStore.FDOProfile().FDOProfile(portainer.FDOProfileID(payload.ProfileID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a FDO Profile with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a FDO Profile with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a FDO Profile with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a FDO Profile with the specified identifier inside the database", err) } fileContent, err := handler.FileService.GetFileContent(profile.FilePath, "") if err != nil { logrus.WithError(err).Info("fdoConfigureDevice: GetFileContent") - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "fdoConfigureDevice: GetFileContent", Err: err} + return httperror.InternalServerError("fdoConfigureDevice: GetFileContent", err) } fdoClient, err := handler.newFDOClient() if err != nil { logrus.WithError(err).Info("fdoConfigureDevice: newFDOClient()") - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "fdoConfigureDevice: newFDOClient()", Err: err} + return httperror.InternalServerError("fdoConfigureDevice: newFDOClient()", err) } // enable fdo_sys @@ -103,7 +103,7 @@ func (handler *Handler) fdoConfigureDevice(w http.ResponseWriter, r *http.Reques "bytes": []string{"F5"}, // this is "true" in CBOR }, []byte("")); err != nil { logrus.WithError(err).Info("fdoConfigureDevice: PutDeviceSVIRaw()") - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "fdoConfigureDevice: PutDeviceSVIRaw()", Err: err} + return httperror.InternalServerError("fdoConfigureDevice: PutDeviceSVIRaw()", err) } if err = fdoClient.PutDeviceSVIRaw(url.Values{ @@ -114,7 +114,7 @@ func (handler *Handler) fdoConfigureDevice(w http.ResponseWriter, r *http.Reques "filename": []string{"DEVICE_edgeid.txt"}, }, []byte(payload.EdgeID)); err != nil { logrus.WithError(err).Info("fdoConfigureDevice: PutDeviceSVIRaw(edgeid)") - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "fdoConfigureDevice: PutDeviceSVIRaw(edgeid)", Err: err} + return httperror.InternalServerError("fdoConfigureDevice: PutDeviceSVIRaw(edgeid)", err) } // write down the edgekey @@ -126,7 +126,7 @@ func (handler *Handler) fdoConfigureDevice(w http.ResponseWriter, r *http.Reques "filename": []string{"DEVICE_edgekey.txt"}, }, []byte(payload.EdgeKey)); err != nil { logrus.WithError(err).Info("fdoConfigureDevice: PutDeviceSVIRaw(edgekey)") - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "fdoConfigureDevice: PutDeviceSVIRaw(edgekey)", Err: err} + return httperror.InternalServerError("fdoConfigureDevice: PutDeviceSVIRaw(edgekey)", err) } // write down the device name @@ -138,7 +138,7 @@ func (handler *Handler) fdoConfigureDevice(w http.ResponseWriter, r *http.Reques "filename": []string{"DEVICE_name.txt"}, }, []byte(payload.Name)); err != nil { logrus.WithError(err).Info("fdoConfigureDevice: PutDeviceSVIRaw(name)") - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "fdoConfigureDevice: PutDeviceSVIRaw(name)", Err: err} + return httperror.InternalServerError("fdoConfigureDevice: PutDeviceSVIRaw(name)", err) } // write down the device GUID - used as the EDGE_DEVICE_GUID too @@ -150,7 +150,7 @@ func (handler *Handler) fdoConfigureDevice(w http.ResponseWriter, r *http.Reques "filename": []string{"DEVICE_GUID.txt"}, }, []byte(guid)); err != nil { logrus.WithError(err).Info("fdoConfigureDevice: PutDeviceSVIRaw()") - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "fdoConfigureDevice: PutDeviceSVIRaw()", Err: err} + return httperror.InternalServerError("fdoConfigureDevice: PutDeviceSVIRaw()", err) } if err = fdoClient.PutDeviceSVIRaw(url.Values{ @@ -161,13 +161,13 @@ func (handler *Handler) fdoConfigureDevice(w http.ResponseWriter, r *http.Reques "filename": []string{deploymentScriptName}, }, fileContent); err != nil { logrus.WithError(err).Info("fdoConfigureDevice: PutDeviceSVIRaw()") - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "fdoConfigureDevice: PutDeviceSVIRaw()", Err: err} + return httperror.InternalServerError("fdoConfigureDevice: PutDeviceSVIRaw()", err) } b, err := cbor.Marshal([]string{"/bin/sh", deploymentScriptName}) if err != nil { logrus.WithError(err).Error("failed to marshal string to CBOR") - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "fdoConfigureDevice: PutDeviceSVIRaw() failed to encode", Err: err} + return httperror.InternalServerError("fdoConfigureDevice: PutDeviceSVIRaw() failed to encode", err) } cborBytes := strings.ToUpper(hex.EncodeToString(b)) @@ -181,7 +181,7 @@ func (handler *Handler) fdoConfigureDevice(w http.ResponseWriter, r *http.Reques "bytes": []string{cborBytes}, }, []byte("")); err != nil { logrus.WithError(err).Info("fdoConfigureDevice: PutDeviceSVIRaw()") - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "fdoConfigureDevice: PutDeviceSVIRaw()", Err: err} + return httperror.InternalServerError("fdoConfigureDevice: PutDeviceSVIRaw()", err) } return response.Empty(w) diff --git a/api/http/handler/hostmanagement/fdo/fdo.go b/api/http/handler/hostmanagement/fdo/fdo.go index b5b4c3fb6..aacae2003 100644 --- a/api/http/handler/hostmanagement/fdo/fdo.go +++ b/api/http/handler/hostmanagement/fdo/fdo.go @@ -89,22 +89,22 @@ func (handler *Handler) fdoConfigure(w http.ResponseWriter, r *http.Request) *ht err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { logrus.WithError(err).Error("Invalid request payload") - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } settings := portainer.FDOConfiguration(payload) if err = handler.saveSettings(settings); err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Error saving FDO settings", Err: err} + return httperror.BadRequest("Error saving FDO settings", err) } profiles, err := handler.DataStore.FDOProfile().FDOProfiles() if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Error saving FDO settings", Err: err} + return httperror.InternalServerError("Error saving FDO settings", err) } if len(profiles) == 0 { err = handler.addDefaultProfile() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, err.Error(), err} + return httperror.InternalServerError(err.Error(), err) } } diff --git a/api/http/handler/hostmanagement/fdo/list.go b/api/http/handler/hostmanagement/fdo/list.go index 69b36692a..ce94bcc6e 100644 --- a/api/http/handler/hostmanagement/fdo/list.go +++ b/api/http/handler/hostmanagement/fdo/list.go @@ -25,14 +25,14 @@ func (handler *Handler) fdoListAll(w http.ResponseWriter, r *http.Request) *http fdoClient, err := handler.newFDOClient() if err != nil { logrus.WithError(err).Info("fdoListAll: newFDOClient()") - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "fdoRegisterDevice: newFDOClient()", Err: err} + return httperror.InternalServerError("fdoRegisterDevice: newFDOClient()", err) } // Get all vouchers guids, err := fdoClient.GetVouchers() if err != nil { logrus.WithError(err).Info("fdoListAll: GetVouchers()") - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "fdoListAll: GetVouchers()", Err: err} + return httperror.InternalServerError("fdoListAll: GetVouchers()", err) } return response.JSON(w, guids) diff --git a/api/http/handler/hostmanagement/fdo/profile_create.go b/api/http/handler/hostmanagement/fdo/profile_create.go index 8752c6d05..f4837618d 100644 --- a/api/http/handler/hostmanagement/fdo/profile_create.go +++ b/api/http/handler/hostmanagement/fdo/profile_create.go @@ -45,29 +45,29 @@ func (payload *createProfileFromFileContentPayload) Validate(r *http.Request) er func (handler *Handler) createProfile(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { method, err := request.RetrieveQueryParameter(r, "method", false) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: method", err} + return httperror.BadRequest("Invalid query parameter: method", err) } switch method { case "editor": return handler.createFDOProfileFromFileContent(w, r) } - return &httperror.HandlerError{http.StatusBadRequest, "Invalid method. Value must be one of: editor", errors.New("invalid method")} + return httperror.BadRequest("Invalid method. Value must be one of: editor", errors.New("invalid method")) } func (handler *Handler) createFDOProfileFromFileContent(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { var payload createProfileFromFileContentPayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } isUnique, err := handler.checkUniqueProfileName(payload.Name, -1) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, err.Error(), err} + return httperror.InternalServerError(err.Error(), err) } if !isUnique { - return &httperror.HandlerError{http.StatusConflict, fmt.Sprintf("A profile with the name '%s' already exists", payload.Name), errors.New("a profile already exists with this name")} + return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: fmt.Sprintf("A profile with the name '%s' already exists", payload.Name), Err: errors.New("a profile already exists with this name")} } profileID := handler.DataStore.FDOProfile().GetNextIdentifier() @@ -78,14 +78,14 @@ func (handler *Handler) createFDOProfileFromFileContent(w http.ResponseWriter, r filePath, err := handler.FileService.StoreFDOProfileFileFromBytes(strconv.Itoa(int(profile.ID)), []byte(payload.ProfileFileContent)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist profile file on disk", err} + return httperror.InternalServerError("Unable to persist profile file on disk", err) } profile.FilePath = filePath profile.DateCreated = time.Now().Unix() err = handler.DataStore.FDOProfile().Create(profile) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist the profile inside the database", err} + return httperror.InternalServerError("Unable to persist the profile inside the database", err) } return response.JSON(w, profile) diff --git a/api/http/handler/hostmanagement/fdo/profile_delete.go b/api/http/handler/hostmanagement/fdo/profile_delete.go index b3210602d..eadd5ab26 100644 --- a/api/http/handler/hostmanagement/fdo/profile_delete.go +++ b/api/http/handler/hostmanagement/fdo/profile_delete.go @@ -24,12 +24,12 @@ import ( func (handler *Handler) deleteProfile(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { id, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Bad request", errors.New("missing 'id' query parameter")} + return httperror.BadRequest("Bad request", errors.New("missing 'id' query parameter")) } err = handler.DataStore.FDOProfile().Delete(portainer.FDOProfileID(id)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to delete Profile", err} + return httperror.InternalServerError("Unable to delete Profile", err) } return response.Empty(w) diff --git a/api/http/handler/hostmanagement/fdo/profile_duplicate.go b/api/http/handler/hostmanagement/fdo/profile_duplicate.go index 085468e92..8ead56a0c 100644 --- a/api/http/handler/hostmanagement/fdo/profile_duplicate.go +++ b/api/http/handler/hostmanagement/fdo/profile_duplicate.go @@ -26,24 +26,24 @@ import ( func (handler *Handler) duplicateProfile(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { id, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Bad request", errors.New("missing 'id' query parameter")} + return httperror.BadRequest("Bad request", errors.New("missing 'id' query parameter")) } originalProfile, err := handler.DataStore.FDOProfile().FDOProfile(portainer.FDOProfileID(id)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a FDO Profile with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a FDO Profile with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a FDO Profile with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a FDO Profile with the specified identifier inside the database", err) } fileContent, err := handler.FileService.GetFileContent(originalProfile.FilePath, "") if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve Profile file content", err} + return httperror.InternalServerError("Unable to retrieve Profile file content", err) } profileID := handler.DataStore.FDOProfile().GetNextIdentifier() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to duplicate Profile", err} + return httperror.InternalServerError("Unable to duplicate Profile", err) } newProfile := &portainer.FDOProfile{ @@ -53,14 +53,14 @@ func (handler *Handler) duplicateProfile(w http.ResponseWriter, r *http.Request) filePath, err := handler.FileService.StoreFDOProfileFileFromBytes(strconv.Itoa(int(newProfile.ID)), fileContent) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist profile file on disk", err} + return httperror.InternalServerError("Unable to persist profile file on disk", err) } newProfile.FilePath = filePath newProfile.DateCreated = time.Now().Unix() err = handler.DataStore.FDOProfile().Create(newProfile) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist the profile inside the database", err} + return httperror.InternalServerError("Unable to persist the profile inside the database", err) } return response.JSON(w, newProfile) diff --git a/api/http/handler/hostmanagement/fdo/profile_inspect.go b/api/http/handler/hostmanagement/fdo/profile_inspect.go index c7882213f..5d35e6908 100644 --- a/api/http/handler/hostmanagement/fdo/profile_inspect.go +++ b/api/http/handler/hostmanagement/fdo/profile_inspect.go @@ -29,17 +29,17 @@ type fdoProfileResponse struct { func (handler *Handler) fdoProfileInspect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { id, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Bad request", errors.New("missing 'id' query parameter")} + return httperror.BadRequest("Bad request", errors.New("missing 'id' query parameter")) } profile, err := handler.DataStore.FDOProfile().FDOProfile(portainer.FDOProfileID(id)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve Profile", err} + return httperror.InternalServerError("Unable to retrieve Profile", err) } fileContent, err := handler.FileService.GetFileContent(profile.FilePath, "") if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve Profile file content", err} + return httperror.InternalServerError("Unable to retrieve Profile file content", err) } return response.JSON(w, fdoProfileResponse{ diff --git a/api/http/handler/hostmanagement/fdo/profile_list.go b/api/http/handler/hostmanagement/fdo/profile_list.go index e3b0c23de..2e190a9c9 100644 --- a/api/http/handler/hostmanagement/fdo/profile_list.go +++ b/api/http/handler/hostmanagement/fdo/profile_list.go @@ -24,7 +24,7 @@ func (handler *Handler) fdoProfileList(w http.ResponseWriter, r *http.Request) * profiles, err := handler.DataStore.FDOProfile().FDOProfiles() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, err.Error(), err} + return httperror.InternalServerError(err.Error(), err) } return response.JSON(w, profiles) diff --git a/api/http/handler/hostmanagement/fdo/profile_update.go b/api/http/handler/hostmanagement/fdo/profile_update.go index cf60f43bf..777772523 100644 --- a/api/http/handler/hostmanagement/fdo/profile_update.go +++ b/api/http/handler/hostmanagement/fdo/profile_update.go @@ -27,40 +27,40 @@ import ( func (handler *Handler) updateProfile(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { id, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Bad request", errors.New("missing 'id' query parameter")} + return httperror.BadRequest("Bad request", errors.New("missing 'id' query parameter")) } var payload createProfileFromFileContentPayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } profile, err := handler.DataStore.FDOProfile().FDOProfile(portainer.FDOProfileID(id)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a FDO Profile with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a FDO Profile with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a FDO Profile with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a FDO Profile with the specified identifier inside the database", err) } isUnique, err := handler.checkUniqueProfileName(payload.Name, id) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, err.Error(), err} + return httperror.InternalServerError(err.Error(), err) } if !isUnique { - return &httperror.HandlerError{http.StatusConflict, fmt.Sprintf("A profile with the name '%s' already exists", payload.Name), errors.New("a profile already exists with this name")} + return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: fmt.Sprintf("A profile with the name '%s' already exists", payload.Name), Err: errors.New("a profile already exists with this name")} } filePath, err := handler.FileService.StoreFDOProfileFileFromBytes(strconv.Itoa(int(profile.ID)), []byte(payload.ProfileFileContent)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to update profile", err} + return httperror.InternalServerError("Unable to update profile", err) } profile.FilePath = filePath profile.Name = payload.Name err = handler.DataStore.FDOProfile().Update(profile.ID, profile) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to update profile", err} + return httperror.InternalServerError("Unable to update profile", err) } return response.JSON(w, profile) diff --git a/api/http/handler/hostmanagement/fdo/register.go b/api/http/handler/hostmanagement/fdo/register.go index ebfce96af..ce87c0226 100644 --- a/api/http/handler/hostmanagement/fdo/register.go +++ b/api/http/handler/hostmanagement/fdo/register.go @@ -30,19 +30,19 @@ func (handler *Handler) fdoRegisterDevice(w http.ResponseWriter, r *http.Request ov, filename, err := request.RetrieveMultiPartFormFile(r, "voucher") if err != nil { logrus.WithField("filename", filename).WithError(err).Info("fdoRegisterDevice: readVoucher()") - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "fdoRegisterDevice: read Voucher()", Err: err} + return httperror.InternalServerError("fdoRegisterDevice: read Voucher()", err) } fdoClient, err := handler.newFDOClient() if err != nil { logrus.WithError(err).Info("fdoRegisterDevice: newFDOClient()") - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "fdoRegisterDevice: newFDOClient()", Err: err} + return httperror.InternalServerError("fdoRegisterDevice: newFDOClient()", err) } guid, err := fdoClient.PostVoucher(ov) if err != nil { logrus.WithError(err).Info("fdoRegisterDevice: PostVoucher()") - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "fdoRegisterDevice: PostVoucher()", Err: err} + return httperror.InternalServerError("fdoRegisterDevice: PostVoucher()", err) } return response.JSON(w, registerDeviceResponse{guid}) diff --git a/api/http/handler/hostmanagement/openamt/amtactivation.go b/api/http/handler/hostmanagement/openamt/amtactivation.go index c4d86f779..e2c8f0922 100644 --- a/api/http/handler/hostmanagement/openamt/amtactivation.go +++ b/api/http/handler/hostmanagement/openamt/amtactivation.go @@ -29,44 +29,44 @@ import ( func (handler *Handler) openAMTActivate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment identifier route variable", err} + return httperror.BadRequest("Invalid environment identifier route variable", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if err == bolterrors.ErrObjectNotFound { - return &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Unable to find an endpoint with the specified identifier inside the database", Err: err} + return httperror.NotFound("Unable to find an endpoint with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to find an endpoint with the specified identifier inside the database", Err: err} + return httperror.InternalServerError("Unable to find an endpoint with the specified identifier inside the database", err) } else if !endpointutils.IsAgentEndpoint(endpoint) { errMsg := fmt.Sprintf("%s is not an agent environment", endpoint.Name) - return &httperror.HandlerError{http.StatusBadRequest, errMsg, errors.New(errMsg)} + return httperror.BadRequest(errMsg, errors.New(errMsg)) } settings, err := handler.DataStore.Settings().Settings() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve settings from the database", err} + return httperror.InternalServerError("Unable to retrieve settings from the database", err) } err = handler.activateDevice(endpoint, *settings) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to activate device", err} + return httperror.InternalServerError("Unable to activate device", err) } hostInfo, _, err := handler.getEndpointAMTInfo(endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve AMT information", Err: err} + return httperror.InternalServerError("Unable to retrieve AMT information", err) } if hostInfo.ControlModeRaw < 1 { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Failed to activate device", Err: errors.New("failed to activate device")} + return httperror.InternalServerError("Failed to activate device", errors.New("failed to activate device")) } if hostInfo.UUID == "" { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve device UUID", Err: errors.New("unable to retrieve device UUID")} + return httperror.InternalServerError("Unable to retrieve device UUID", errors.New("unable to retrieve device UUID")) } endpoint.AMTDeviceGUID = hostInfo.UUID err = handler.DataStore.Endpoint().UpdateEndpoint(endpoint.ID, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist environment changes inside the database", err} + return httperror.InternalServerError("Unable to persist environment changes inside the database", err) } return response.Empty(w) diff --git a/api/http/handler/hostmanagement/openamt/amtconfiguration.go b/api/http/handler/hostmanagement/openamt/amtconfiguration.go index 677343352..774814ab1 100644 --- a/api/http/handler/hostmanagement/openamt/amtconfiguration.go +++ b/api/http/handler/hostmanagement/openamt/amtconfiguration.go @@ -74,25 +74,25 @@ func (handler *Handler) openAMTConfigure(w http.ResponseWriter, r *http.Request) err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { logrus.WithError(err).Error("Invalid request payload") - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } if payload.Enabled { certificateErr := validateCertificate(payload.CertFileContent, payload.CertFilePassword) if certificateErr != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Error validating certificate", Err: certificateErr} + return httperror.BadRequest("Error validating certificate", certificateErr) } err = handler.enableOpenAMT(payload) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Error enabling OpenAMT", Err: err} + return httperror.BadRequest("Error enabling OpenAMT", err) } return response.Empty(w) } err = handler.disableOpenAMT() if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Error disabling OpenAMT", Err: err} + return httperror.BadRequest("Error disabling OpenAMT", err) } return response.Empty(w) } diff --git a/api/http/handler/hostmanagement/openamt/amtdevices.go b/api/http/handler/hostmanagement/openamt/amtdevices.go index 5459e2ac1..68bcdda6f 100644 --- a/api/http/handler/hostmanagement/openamt/amtdevices.go +++ b/api/http/handler/hostmanagement/openamt/amtdevices.go @@ -28,14 +28,14 @@ import ( func (handler *Handler) openAMTDevices(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment identifier route variable", err} + return httperror.BadRequest("Invalid environment identifier route variable", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if err == bolterrors.ErrObjectNotFound { - return &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Unable to find an endpoint with the specified identifier inside the database", Err: err} + return httperror.NotFound("Unable to find an endpoint with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to find an endpoint with the specified identifier inside the database", Err: err} + return httperror.InternalServerError("Unable to find an endpoint with the specified identifier inside the database", err) } if endpoint.AMTDeviceGUID == "" { @@ -44,12 +44,12 @@ func (handler *Handler) openAMTDevices(w http.ResponseWriter, r *http.Request) * settings, err := handler.DataStore.Settings().Settings() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve settings from the database", err} + return httperror.InternalServerError("Unable to retrieve settings from the database", err) } device, err := handler.OpenAMTService.DeviceInformation(settings.OpenAMTConfiguration, endpoint.AMTDeviceGUID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve device information", err} + return httperror.InternalServerError("Unable to retrieve device information", err) } devices := []portainer.OpenAMTDeviceInformation{ @@ -87,25 +87,25 @@ func (payload *deviceActionPayload) Validate(r *http.Request) error { func (handler *Handler) deviceAction(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { deviceID, err := request.RetrieveRouteVariableValue(r, "deviceId") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid device identifier route variable", err} + return httperror.BadRequest("Invalid device identifier route variable", err) } var payload deviceActionPayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { logrus.WithError(err).Error("Invalid request payload") - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } settings, err := handler.DataStore.Settings().Settings() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve settings from the database", err} + return httperror.InternalServerError("Unable to retrieve settings from the database", err) } err = handler.OpenAMTService.ExecuteDeviceAction(settings.OpenAMTConfiguration, deviceID, payload.Action) if err != nil { logrus.WithError(err).Error("Error executing device action") - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Error executing device action", Err: err} + return httperror.BadRequest("Error executing device action", err) } return response.Empty(w) @@ -144,30 +144,30 @@ type AuthorizationResponse struct { func (handler *Handler) deviceFeatures(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { deviceID, err := request.RetrieveRouteVariableValue(r, "deviceId") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid device identifier route variable", err} + return httperror.BadRequest("Invalid device identifier route variable", err) } var payload deviceFeaturesPayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { logrus.WithError(err).Error("Invalid request payload") - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } settings, err := handler.DataStore.Settings().Settings() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve settings from the database", err} + return httperror.InternalServerError("Unable to retrieve settings from the database", err) } _, err = handler.OpenAMTService.DeviceInformation(settings.OpenAMTConfiguration, deviceID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve device information", err} + return httperror.InternalServerError("Unable to retrieve device information", err) } token, err := handler.OpenAMTService.EnableDeviceFeatures(settings.OpenAMTConfiguration, deviceID, payload.Features) if err != nil { logrus.WithError(err).Error("Error executing device action") - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Error executing device action", Err: err} + return httperror.BadRequest("Error executing device action", err) } authorizationResponse := AuthorizationResponse{ diff --git a/api/http/handler/hostmanagement/openamt/amtrpc.go b/api/http/handler/hostmanagement/openamt/amtrpc.go index 8f9595f5f..b1065cb81 100644 --- a/api/http/handler/hostmanagement/openamt/amtrpc.go +++ b/api/http/handler/hostmanagement/openamt/amtrpc.go @@ -57,21 +57,21 @@ const ( func (handler *Handler) openAMTHostInfo(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment identifier route variable", err} + return httperror.BadRequest("Invalid environment identifier route variable", err) } logrus.WithField("endpointID", endpointID).Info("OpenAMTHostInfo") endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if err == bolterrors.ErrObjectNotFound { - return &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Unable to find an endpoint with the specified identifier inside the database", Err: err} + return httperror.NotFound("Unable to find an endpoint with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to find an endpoint with the specified identifier inside the database", Err: err} + return httperror.InternalServerError("Unable to find an endpoint with the specified identifier inside the database", err) } amtInfo, output, err := handler.getEndpointAMTInfo(endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: output, Err: err} + return httperror.InternalServerError(output, err) } return response.JSON(w, amtInfo) diff --git a/api/http/handler/kubernetes/kubernetes_config.go b/api/http/handler/kubernetes/kubernetes_config.go index a5dc95b3d..02fdc2f1d 100644 --- a/api/http/handler/kubernetes/kubernetes_config.go +++ b/api/http/handler/kubernetes/kubernetes_config.go @@ -36,11 +36,11 @@ import ( func (handler *Handler) getKubernetesConfig(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { tokenData, err := security.RetrieveTokenData(r) if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access environment", err} + return httperror.Forbidden("Permission denied to access environment", err) } bearerToken, err := handler.jwtService.GenerateTokenForKubeconfig(tokenData) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to generate JWT token", err} + return httperror.InternalServerError("Unable to generate JWT token", err) } endpoints, handlerErr := handler.filterUserKubeEndpoints(r) @@ -48,7 +48,7 @@ func (handler *Handler) getKubernetesConfig(w http.ResponseWriter, r *http.Reque return handlerErr } if len(endpoints) == 0 { - return &httperror.HandlerError{http.StatusBadRequest, "empty endpoints list", errors.New("empty endpoints list")} + return httperror.BadRequest("empty endpoints list", errors.New("empty endpoints list")) } config, handlerErr := handler.buildConfig(r, tokenData, bearerToken, endpoints) @@ -67,17 +67,17 @@ func (handler *Handler) filterUserKubeEndpoints(r *http.Request) ([]portainer.En _ = request.RetrieveJSONQueryParameter(r, "excludeIds", &excludeEndpointIDs, true) if len(endpointIDs) > 0 && len(excludeEndpointIDs) > 0 { - return nil, &httperror.HandlerError{http.StatusBadRequest, "Can't provide both 'ids' and 'excludeIds' parameters", errors.New("invalid parameters")} + return nil, httperror.BadRequest("Can't provide both 'ids' and 'excludeIds' parameters", errors.New("invalid parameters")) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return nil, &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return nil, httperror.InternalServerError("Unable to retrieve info from request context", err) } endpointGroups, err := handler.dataStore.EndpointGroup().EndpointGroups() if err != nil { - return nil, &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve environment groups from the database", err} + return nil, httperror.InternalServerError("Unable to retrieve environment groups from the database", err) } if len(endpointIDs) > 0 { @@ -85,7 +85,7 @@ func (handler *Handler) filterUserKubeEndpoints(r *http.Request) ([]portainer.En for _, endpointID := range endpointIDs { endpoint, err := handler.dataStore.Endpoint().Endpoint(endpointID) if err != nil { - return nil, &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve environment from the database", err} + return nil, httperror.InternalServerError("Unable to retrieve environment from the database", err) } if !endpointutils.IsKubernetesEndpoint(endpoint) { continue @@ -99,7 +99,7 @@ func (handler *Handler) filterUserKubeEndpoints(r *http.Request) ([]portainer.En var kubeEndpoints []portainer.Endpoint endpoints, err := handler.dataStore.Endpoint().Endpoints() if err != nil { - return nil, &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve environments from the database", err} + return nil, httperror.InternalServerError("Unable to retrieve environments from the database", err) } for _, endpoint := range endpoints { if !endpointutils.IsKubernetesEndpoint(&endpoint) { @@ -188,7 +188,7 @@ func writeFileContent(w http.ResponseWriter, r *http.Request, endpoints []portai if r.Header.Get("Accept") == "text/yaml" { yaml, err := kcli.GenerateYAML(config) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Failed to generate Kubeconfig", err} + return httperror.InternalServerError("Failed to generate Kubeconfig", err) } w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; %s.yaml", filenameBase)) diff --git a/api/http/handler/kubernetes/kubernetes_nodes_limits.go b/api/http/handler/kubernetes/kubernetes_nodes_limits.go index 796c642b5..293b020f0 100644 --- a/api/http/handler/kubernetes/kubernetes_nodes_limits.go +++ b/api/http/handler/kubernetes/kubernetes_nodes_limits.go @@ -29,24 +29,24 @@ import ( func (handler *Handler) getKubernetesNodesLimits(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid environment identifier route variable", err} + return httperror.BadRequest("Invalid environment identifier route variable", err) } endpoint, err := handler.dataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.dataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } cli, err := handler.kubernetesClientFactory.GetKubeClient(endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to create Kubernetes client", err} + return httperror.InternalServerError("Unable to create Kubernetes client", err) } nodesLimits, err := cli.GetNodesLimits() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve nodes limits", err} + return httperror.InternalServerError("Unable to retrieve nodes limits", err) } return response.JSON(w, nodesLimits) diff --git a/api/http/handler/kubernetes/namespaces_toggle_system.go b/api/http/handler/kubernetes/namespaces_toggle_system.go index d60a13e4e..a77cd2f94 100644 --- a/api/http/handler/kubernetes/namespaces_toggle_system.go +++ b/api/http/handler/kubernetes/namespaces_toggle_system.go @@ -37,28 +37,28 @@ func (payload *namespacesToggleSystemPayload) Validate(r *http.Request) error { func (handler *Handler) namespacesToggleSystem(rw http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpoint, err := middlewares.FetchEndpoint(r) if err != nil { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment on request context", err} + return httperror.NotFound("Unable to find an environment on request context", err) } namespaceName, err := request.RetrieveRouteVariableValue(r, "namespace") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid namespace identifier route variable", err} + return httperror.BadRequest("Invalid namespace identifier route variable", err) } var payload namespacesToggleSystemPayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } kubeClient, err := handler.kubernetesClientFactory.GetKubeClient(endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to create kubernetes client", err} + return httperror.InternalServerError("Unable to create kubernetes client", err) } err = kubeClient.ToggleSystemState(namespaceName, payload.System) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to toggle system status", err} + return httperror.InternalServerError("Unable to toggle system status", err) } return response.Empty(rw) diff --git a/api/http/handler/ldap/ldap_check.go b/api/http/handler/ldap/ldap_check.go index 4013d380c..eb6ae056b 100644 --- a/api/http/handler/ldap/ldap_check.go +++ b/api/http/handler/ldap/ldap_check.go @@ -34,19 +34,19 @@ func (handler *Handler) ldapCheck(w http.ResponseWriter, r *http.Request) *httpe var payload checkPayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } settings := &payload.LDAPSettings err = handler.prefillSettings(settings) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to fetch default settings", err} + return httperror.InternalServerError("Unable to fetch default settings", err) } err = handler.LDAPService.TestConnectivity(settings) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to connect to LDAP server", err} + return httperror.InternalServerError("Unable to connect to LDAP server", err) } return response.Empty(w) diff --git a/api/http/handler/registries/proxy_gitlab.go b/api/http/handler/registries/proxy_gitlab.go index 47b5f4169..9e8276a7c 100644 --- a/api/http/handler/registries/proxy_gitlab.go +++ b/api/http/handler/registries/proxy_gitlab.go @@ -10,12 +10,12 @@ import ( func (handler *Handler) proxyRequestsToGitlabAPIWithoutRegistry(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { domain := r.Header.Get("X-Gitlab-Domain") if domain == "" { - return &httperror.HandlerError{http.StatusBadRequest, "No Gitlab domain provided", nil} + return httperror.BadRequest("No Gitlab domain provided", nil) } proxy, err := handler.ProxyManager.CreateGitlabProxy(domain) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to create gitlab proxy", err} + return httperror.InternalServerError("Unable to create gitlab proxy", err) } http.StripPrefix("/registries/proxies/gitlab", proxy).ServeHTTP(w, r) diff --git a/api/http/handler/registries/registry_configure.go b/api/http/handler/registries/registry_configure.go index 0c56e267d..8cbd8547c 100644 --- a/api/http/handler/registries/registry_configure.go +++ b/api/http/handler/registries/registry_configure.go @@ -101,28 +101,28 @@ func (payload *registryConfigurePayload) Validate(r *http.Request) error { func (handler *Handler) registryConfigure(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } if !securityContext.IsAdmin { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to configure registry", httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Permission denied to configure registry", httperrors.ErrResourceAccessDenied) } payload := ®istryConfigurePayload{} err = payload.Validate(r) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } registryID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid registry identifier route variable", err} + return httperror.BadRequest("Invalid registry identifier route variable", err) } registry, err := handler.DataStore.Registry().Registry(portainer.RegistryID(registryID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a registry with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a registry with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a registry with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a registry with the specified identifier inside the database", err) } registry.ManagementConfiguration = &portainer.RegistryManagementConfiguration{ @@ -154,19 +154,19 @@ func (handler *Handler) registryConfigure(w http.ResponseWriter, r *http.Request certPath, err := handler.FileService.StoreRegistryManagementFileFromBytes(folder, "cert.pem", payload.TLSCertFile) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist TLS certificate file on disk", err} + return httperror.InternalServerError("Unable to persist TLS certificate file on disk", err) } registry.ManagementConfiguration.TLSConfig.TLSCertPath = certPath keyPath, err := handler.FileService.StoreRegistryManagementFileFromBytes(folder, "key.pem", payload.TLSKeyFile) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist TLS key file on disk", err} + return httperror.InternalServerError("Unable to persist TLS key file on disk", err) } registry.ManagementConfiguration.TLSConfig.TLSKeyPath = keyPath cacertPath, err := handler.FileService.StoreRegistryManagementFileFromBytes(folder, "ca.pem", payload.TLSCACertFile) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist TLS CA certificate file on disk", err} + return httperror.InternalServerError("Unable to persist TLS CA certificate file on disk", err) } registry.ManagementConfiguration.TLSConfig.TLSCACertPath = cacertPath } @@ -174,7 +174,7 @@ func (handler *Handler) registryConfigure(w http.ResponseWriter, r *http.Request err = handler.DataStore.Registry().UpdateRegistry(registry.ID, registry) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist registry changes inside the database", err} + return httperror.InternalServerError("Unable to persist registry changes inside the database", err) } return response.Empty(w) diff --git a/api/http/handler/registries/registry_create.go b/api/http/handler/registries/registry_create.go index bb736fb50..b79ca5eaf 100644 --- a/api/http/handler/registries/registry_create.go +++ b/api/http/handler/registries/registry_create.go @@ -93,16 +93,16 @@ func (payload *registryCreatePayload) Validate(_ *http.Request) error { func (handler *Handler) registryCreate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } if !securityContext.IsAdmin { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to create registry", httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Permission denied to create registry", httperrors.ErrResourceAccessDenied) } var payload registryCreatePayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } registry := &portainer.Registry{ @@ -123,20 +123,20 @@ func (handler *Handler) registryCreate(w http.ResponseWriter, r *http.Request) * registries, err := rs.Registries() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve registries from the database", err} + return httperror.InternalServerError("Unable to retrieve registries from the database", err) } for _, r := range registries { if r.Name == registry.Name { - return &httperror.HandlerError{http.StatusConflict, "Another registry with the same name already exists", errors.New("A registry is already defined with this name")} + return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Another registry with the same name already exists", Err: errors.New("A registry is already defined with this name")} } if handler.registriesHaveSameURLAndCredentials(&r, registry) { - return &httperror.HandlerError{http.StatusConflict, "Another registry with the same URL and credentials already exists", errors.New("A registry is already defined for this URL and credentials")} + return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Another registry with the same URL and credentials already exists", Err: errors.New("A registry is already defined for this URL and credentials")} } } err = rs.Create(registry) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist the registry inside the database", err} + return httperror.InternalServerError("Unable to persist the registry inside the database", err) } hideFields(registry, true) diff --git a/api/http/handler/registries/registry_delete.go b/api/http/handler/registries/registry_delete.go index e2e3d4f64..62088b189 100644 --- a/api/http/handler/registries/registry_delete.go +++ b/api/http/handler/registries/registry_delete.go @@ -27,27 +27,27 @@ import ( func (handler *Handler) registryDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } if !securityContext.IsAdmin { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to delete registry", httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Permission denied to delete registry", httperrors.ErrResourceAccessDenied) } registryID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid registry identifier route variable", err} + return httperror.BadRequest("Invalid registry identifier route variable", err) } _, err = handler.DataStore.Registry().Registry(portainer.RegistryID(registryID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a registry with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a registry with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a registry with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a registry with the specified identifier inside the database", err) } err = handler.DataStore.Registry().DeleteRegistry(portainer.RegistryID(registryID)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove the registry from the database", err} + return httperror.InternalServerError("Unable to remove the registry from the database", err) } return response.Empty(w) diff --git a/api/http/handler/registries/registry_inspect.go b/api/http/handler/registries/registry_inspect.go index 600873f91..d100d4d1d 100644 --- a/api/http/handler/registries/registry_inspect.go +++ b/api/http/handler/registries/registry_inspect.go @@ -29,22 +29,22 @@ import ( func (handler *Handler) registryInspect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { hasAccess, isAdmin, err := handler.userHasRegistryAccess(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } if !hasAccess { - return &httperror.HandlerError{http.StatusForbidden, "Access denied to resource", httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Access denied to resource", httperrors.ErrResourceAccessDenied) } registryID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid registry identifier route variable", err} + return httperror.BadRequest("Invalid registry identifier route variable", err) } registry, err := handler.DataStore.Registry().Registry(portainer.RegistryID(registryID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a registry with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a registry with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a registry with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a registry with the specified identifier inside the database", err) } hideFields(registry, !isAdmin) diff --git a/api/http/handler/registries/registry_list.go b/api/http/handler/registries/registry_list.go index 33138121a..31218e8a2 100644 --- a/api/http/handler/registries/registry_list.go +++ b/api/http/handler/registries/registry_list.go @@ -25,15 +25,15 @@ import ( func (handler *Handler) registryList(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } if !securityContext.IsAdmin { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to list registries, use /endpoints/:endpointId/registries route instead", httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Permission denied to list registries, use /endpoints/:endpointId/registries route instead", httperrors.ErrResourceAccessDenied) } registries, err := handler.DataStore.Registry().Registries() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve registries from the database", err} + return httperror.InternalServerError("Unable to retrieve registries from the database", err) } return response.JSON(w, registries) diff --git a/api/http/handler/registries/registry_update.go b/api/http/handler/registries/registry_update.go index 3daa84afe..4e03baf20 100644 --- a/api/http/handler/registries/registry_update.go +++ b/api/http/handler/registries/registry_update.go @@ -2,9 +2,10 @@ package registries import ( "errors" - "github.com/portainer/portainer/api/internal/endpointutils" "net/http" + "github.com/portainer/portainer/api/internal/endpointutils" + httperror "github.com/portainer/libhttp/error" "github.com/portainer/libhttp/request" "github.com/portainer/libhttp/response" @@ -58,34 +59,34 @@ func (payload *registryUpdatePayload) Validate(r *http.Request) error { func (handler *Handler) registryUpdate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } if !securityContext.IsAdmin { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to update registry", httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Permission denied to update registry", httperrors.ErrResourceAccessDenied) } registryID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid registry identifier route variable", err} + return httperror.BadRequest("Invalid registry identifier route variable", err) } registry, err := handler.DataStore.Registry().Registry(portainer.RegistryID(registryID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a registry with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a registry with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a registry with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a registry with the specified identifier inside the database", err) } registries, err := handler.DataStore.Registry().Registries() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve registries from the database", err} + return httperror.InternalServerError("Unable to retrieve registries from the database", err) } var payload registryUpdatePayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } if payload.Name != nil { @@ -97,7 +98,7 @@ func (handler *Handler) registryUpdate(w http.ResponseWriter, r *http.Request) * // see https://portainer.atlassian.net/browse/EE-2706 for more details for _, r := range registries { if r.ID != registry.ID && r.Name == registry.Name { - return &httperror.HandlerError{http.StatusConflict, "Another registry with the same name already exists", errors.New("A registry is already defined with this name")} + return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Another registry with the same name already exists", Err: errors.New("A registry is already defined with this name")} } } @@ -146,7 +147,7 @@ func (handler *Handler) registryUpdate(w http.ResponseWriter, r *http.Request) * for _, r := range registries { if r.ID != registry.ID && handler.registriesHaveSameURLAndCredentials(&r, registry) { - return &httperror.HandlerError{http.StatusConflict, "Another registry with the same URL and credentials already exists", errors.New("A registry is already defined for this URL and credentials")} + return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Another registry with the same URL and credentials already exists", Err: errors.New("A registry is already defined for this URL and credentials")} } } } @@ -158,13 +159,13 @@ func (handler *Handler) registryUpdate(w http.ResponseWriter, r *http.Request) * for endpointID, endpointAccess := range registry.RegistryAccesses { endpoint, err := handler.DataStore.Endpoint().Endpoint(endpointID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to update access to registry", err} + return httperror.InternalServerError("Unable to update access to registry", err) } if endpointutils.IsKubernetesEndpoint(endpoint) { err = handler.updateEndpointRegistryAccess(endpoint, registry, endpointAccess) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to update access to registry", err} + return httperror.InternalServerError("Unable to update access to registry", err) } } } @@ -176,7 +177,7 @@ func (handler *Handler) registryUpdate(w http.ResponseWriter, r *http.Request) * err = handler.DataStore.Registry().UpdateRegistry(registry.ID, registry) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist registry changes inside the database", err} + return httperror.InternalServerError("Unable to persist registry changes inside the database", err) } return response.JSON(w, registry) diff --git a/api/http/handler/resourcecontrols/resourcecontrol_create.go b/api/http/handler/resourcecontrols/resourcecontrol_create.go index 0763e68a8..b3bd5741e 100644 --- a/api/http/handler/resourcecontrols/resourcecontrol_create.go +++ b/api/http/handler/resourcecontrols/resourcecontrol_create.go @@ -72,15 +72,15 @@ func (handler *Handler) resourceControlCreate(w http.ResponseWriter, r *http.Req var payload resourceControlCreatePayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } rc, err := handler.DataStore.ResourceControl().ResourceControlByResourceIDAndType(payload.ResourceID, payload.Type) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve resource controls from the database", err} + return httperror.InternalServerError("Unable to retrieve resource controls from the database", err) } if rc != nil { - return &httperror.HandlerError{http.StatusConflict, "A resource control is already associated to this resource", errResourceControlAlreadyExists} + return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "A resource control is already associated to this resource", Err: errResourceControlAlreadyExists} } var userAccesses = make([]portainer.UserResourceAccess, 0) @@ -113,7 +113,7 @@ func (handler *Handler) resourceControlCreate(w http.ResponseWriter, r *http.Req err = handler.DataStore.ResourceControl().Create(&resourceControl) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist the resource control inside the database", err} + return httperror.InternalServerError("Unable to persist the resource control inside the database", err) } return response.JSON(w, resourceControl) diff --git a/api/http/handler/resourcecontrols/resourcecontrol_delete.go b/api/http/handler/resourcecontrols/resourcecontrol_delete.go index 0e153c8b5..c0922ed44 100644 --- a/api/http/handler/resourcecontrols/resourcecontrol_delete.go +++ b/api/http/handler/resourcecontrols/resourcecontrol_delete.go @@ -25,19 +25,19 @@ import ( func (handler *Handler) resourceControlDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { resourceControlID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid resource control identifier route variable", err} + return httperror.BadRequest("Invalid resource control identifier route variable", err) } _, err = handler.DataStore.ResourceControl().ResourceControl(portainer.ResourceControlID(resourceControlID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a resource control with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a resource control with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a resource control with with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a resource control with with the specified identifier inside the database", err) } err = handler.DataStore.ResourceControl().DeleteResourceControl(portainer.ResourceControlID(resourceControlID)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove the resource control from the database", err} + return httperror.InternalServerError("Unable to remove the resource control from the database", err) } return response.Empty(w) diff --git a/api/http/handler/resourcecontrols/resourcecontrol_update.go b/api/http/handler/resourcecontrols/resourcecontrol_update.go index 6620ef512..c2dd3c0bf 100644 --- a/api/http/handler/resourcecontrols/resourcecontrol_update.go +++ b/api/http/handler/resourcecontrols/resourcecontrol_update.go @@ -54,29 +54,29 @@ func (payload *resourceControlUpdatePayload) Validate(r *http.Request) error { func (handler *Handler) resourceControlUpdate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { resourceControlID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid resource control identifier route variable", err} + return httperror.BadRequest("Invalid resource control identifier route variable", err) } var payload resourceControlUpdatePayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } resourceControl, err := handler.DataStore.ResourceControl().ResourceControl(portainer.ResourceControlID(resourceControlID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a resource control with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a resource control with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a resource control with with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a resource control with with the specified identifier inside the database", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } if !security.AuthorizedResourceControlAccess(resourceControl, securityContext) { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access the resource control", httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Permission denied to access the resource control", httperrors.ErrResourceAccessDenied) } resourceControl.Public = payload.Public @@ -103,12 +103,12 @@ func (handler *Handler) resourceControlUpdate(w http.ResponseWriter, r *http.Req resourceControl.TeamAccesses = teamAccesses if !security.AuthorizedResourceControlUpdate(resourceControl, securityContext) { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to update the resource control", httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Permission denied to update the resource control", httperrors.ErrResourceAccessDenied) } err = handler.DataStore.ResourceControl().UpdateResourceControl(resourceControl.ID, resourceControl) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist resource control changes inside the database", err} + return httperror.InternalServerError("Unable to persist resource control changes inside the database", err) } return response.JSON(w, resourceControl) diff --git a/api/http/handler/roles/role_list.go b/api/http/handler/roles/role_list.go index 5a6a210e0..f94ac001c 100644 --- a/api/http/handler/roles/role_list.go +++ b/api/http/handler/roles/role_list.go @@ -21,7 +21,7 @@ import ( func (handler *Handler) roleList(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { roles, err := handler.DataStore.Role().Roles() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve authorization sets from the database", err} + return httperror.InternalServerError("Unable to retrieve authorization sets from the database", err) } return response.JSON(w, roles) diff --git a/api/http/handler/settings/settings_inspect.go b/api/http/handler/settings/settings_inspect.go index 5f67ab36d..33ba77301 100644 --- a/api/http/handler/settings/settings_inspect.go +++ b/api/http/handler/settings/settings_inspect.go @@ -21,7 +21,7 @@ import ( func (handler *Handler) settingsInspect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { settings, err := handler.DataStore.Settings().Settings() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve the settings from the database", err} + return httperror.InternalServerError("Unable to retrieve the settings from the database", err) } hideFields(settings) diff --git a/api/http/handler/settings/settings_public.go b/api/http/handler/settings/settings_public.go index 921966a3d..96191f983 100644 --- a/api/http/handler/settings/settings_public.go +++ b/api/http/handler/settings/settings_public.go @@ -57,7 +57,7 @@ type publicSettingsResponse struct { func (handler *Handler) settingsPublic(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { settings, err := handler.DataStore.Settings().Settings() if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve the settings from the database", Err: err} + return httperror.InternalServerError("Unable to retrieve the settings from the database", err) } publicSettings := generatePublicSettings(settings) diff --git a/api/http/handler/settings/settings_update.go b/api/http/handler/settings/settings_update.go index 19733ff9e..c49fb8ac5 100644 --- a/api/http/handler/settings/settings_update.go +++ b/api/http/handler/settings/settings_update.go @@ -106,12 +106,12 @@ func (handler *Handler) settingsUpdate(w http.ResponseWriter, r *http.Request) * var payload settingsUpdatePayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } settings, err := handler.DataStore.Settings().Settings() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve the settings from the database", err} + return httperror.InternalServerError("Unable to retrieve the settings from the database", err) } if handler.demoService.IsDemo() { @@ -139,7 +139,7 @@ func (handler *Handler) settingsUpdate(w http.ResponseWriter, r *http.Request) * if newHelmRepo != settings.HelmRepositoryURL && newHelmRepo != portainer.DefaultHelmRepositoryURL { err := libhelm.ValidateHelmRepositoryURL(*payload.HelmRepositoryURL) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid Helm repository URL. Must correspond to a valid URL format", err} + return httperror.BadRequest("Invalid Helm repository URL. Must correspond to a valid URL format", err) } } @@ -205,7 +205,7 @@ func (handler *Handler) settingsUpdate(w http.ResponseWriter, r *http.Request) * if payload.SnapshotInterval != nil && *payload.SnapshotInterval != settings.SnapshotInterval { err := handler.updateSnapshotInterval(settings, *payload.SnapshotInterval) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to update snapshot interval", err} + return httperror.InternalServerError("Unable to update snapshot interval", err) } } @@ -240,7 +240,7 @@ func (handler *Handler) settingsUpdate(w http.ResponseWriter, r *http.Request) * err = handler.DataStore.Settings().UpdateSettings(settings) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist settings changes inside the database", err} + return httperror.InternalServerError("Unable to persist settings changes inside the database", err) } return response.JSON(w, settings) @@ -265,7 +265,7 @@ func (handler *Handler) updateTLS(settings *portainer.Settings) *httperror.Handl settings.LDAPSettings.TLSConfig.TLSCACertPath = "" err := handler.FileService.DeleteTLSFiles(filesystem.LDAPStorePath) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove TLS files from disk", err} + return httperror.InternalServerError("Unable to remove TLS files from disk", err) } } return nil diff --git a/api/http/handler/ssl/ssl_inspect.go b/api/http/handler/ssl/ssl_inspect.go index 98e6ba618..ec509b8e0 100644 --- a/api/http/handler/ssl/ssl_inspect.go +++ b/api/http/handler/ssl/ssl_inspect.go @@ -23,7 +23,7 @@ import ( func (handler *Handler) sslInspect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { settings, err := handler.SSLService.GetSSLSettings() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Failed to fetch certificate info", err} + return httperror.InternalServerError("Failed to fetch certificate info", err) } return response.JSON(w, settings) diff --git a/api/http/handler/ssl/ssl_update.go b/api/http/handler/ssl/ssl_update.go index 028cbd73b..28dba27b3 100644 --- a/api/http/handler/ssl/ssl_update.go +++ b/api/http/handler/ssl/ssl_update.go @@ -42,20 +42,20 @@ func (handler *Handler) sslUpdate(w http.ResponseWriter, r *http.Request) *httpe var payload sslUpdatePayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } if payload.Cert != nil { err = handler.SSLService.SetCertificates([]byte(*payload.Cert), []byte(*payload.Key)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Failed to save certificate", err} + return httperror.InternalServerError("Failed to save certificate", err) } } if payload.HTTPEnabled != nil { err = handler.SSLService.SetHTTPEnabled(*payload.HTTPEnabled) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Failed to force https", err} + return httperror.InternalServerError("Failed to force https", err) } } diff --git a/api/http/handler/stacks/autoupdate.go b/api/http/handler/stacks/autoupdate.go index 7d6e7dd46..9595d7cd6 100644 --- a/api/http/handler/stacks/autoupdate.go +++ b/api/http/handler/stacks/autoupdate.go @@ -2,7 +2,6 @@ package stacks import ( "log" - "net/http" "time" httperror "github.com/portainer/libhttp/error" @@ -15,7 +14,7 @@ import ( func startAutoupdate(stackID portainer.StackID, interval string, scheduler *scheduler.Scheduler, stackDeployer stacks.StackDeployer, datastore dataservices.DataStore, gitService portainer.GitService) (jobID string, e *httperror.HandlerError) { d, err := time.ParseDuration(interval) if err != nil { - return "", &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Unable to parse stack's auto update interval", Err: err} + return "", httperror.BadRequest("Unable to parse stack's auto update interval", err) } jobID = scheduler.StartJobEvery(d, func() error { @@ -33,5 +32,4 @@ func stopAutoupdate(stackID portainer.StackID, jobID string, scheduler scheduler if err := scheduler.StopJob(jobID); err != nil { log.Printf("[WARN] could not stop the job for the stack %v", stackID) } - } diff --git a/api/http/handler/stacks/create_compose_stack.go b/api/http/handler/stacks/create_compose_stack.go index 134a08784..891b551c2 100644 --- a/api/http/handler/stacks/create_compose_stack.go +++ b/api/http/handler/stacks/create_compose_stack.go @@ -74,14 +74,14 @@ func (handler *Handler) createComposeStackFromFileContent(w http.ResponseWriter, var payload composeStackFromFileContentPayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } payload.Name = handler.ComposeStackManager.NormalizeStackName(payload.Name) isUnique, err := handler.checkUniqueStackNameInDocker(endpoint, payload.Name, 0, false) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to check for name collision", err} + return httperror.InternalServerError("Unable to check for name collision", err) } if !isUnique { @@ -93,7 +93,7 @@ func (handler *Handler) createComposeStackFromFileContent(w http.ResponseWriter, if stack.Type != portainer.DockerComposeStack && stack.EndpointID == endpoint.ID { err := handler.checkAndCleanStackDupFromSwarm(w, r, endpoint, userID, &stack) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } } else { return stackExistsError(payload.Name) @@ -117,7 +117,7 @@ func (handler *Handler) createComposeStackFromFileContent(w http.ResponseWriter, stackFolder := strconv.Itoa(int(stack.ID)) projectPath, err := handler.FileService.StoreStackFileFromBytes(stackFolder, stack.EntryPoint, []byte(payload.StackFileContent)) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to persist Compose file on disk", Err: err} + return httperror.InternalServerError("Unable to persist Compose file on disk", err) } stack.ProjectPath = projectPath @@ -131,14 +131,14 @@ func (handler *Handler) createComposeStackFromFileContent(w http.ResponseWriter, err = handler.deployComposeStack(config, false) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: err.Error(), Err: err} + return httperror.InternalServerError(err.Error(), err) } stack.CreatedBy = config.user.Username err = handler.DataStore.Stack().Create(stack) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to persist the stack inside the database", Err: err} + return httperror.InternalServerError("Unable to persist the stack inside the database", err) } doCleanUp = false @@ -190,7 +190,7 @@ func (handler *Handler) createComposeStackFromGitRepository(w http.ResponseWrite var payload composeStackFromGitRepositoryPayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } payload.Name = handler.ComposeStackManager.NormalizeStackName(payload.Name) @@ -200,7 +200,7 @@ func (handler *Handler) createComposeStackFromGitRepository(w http.ResponseWrite isUnique, err := handler.checkUniqueStackNameInDocker(endpoint, payload.Name, 0, false) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to check for name collision", Err: err} + return httperror.InternalServerError("Unable to check for name collision", err) } if !isUnique { @@ -212,7 +212,7 @@ func (handler *Handler) createComposeStackFromGitRepository(w http.ResponseWrite if stack.Type != portainer.DockerComposeStack && stack.EndpointID == endpoint.ID { err := handler.checkAndCleanStackDupFromSwarm(w, r, endpoint, userID, &stack) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } } else { return stackExistsError(payload.Name) @@ -224,7 +224,7 @@ func (handler *Handler) createComposeStackFromGitRepository(w http.ResponseWrite if payload.AutoUpdate != nil && payload.AutoUpdate.Webhook != "" { isUnique, err := handler.checkUniqueWebhookID(payload.AutoUpdate.Webhook) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to check for webhook ID collision", Err: err} + return httperror.InternalServerError("Unable to check for webhook ID collision", err) } if !isUnique { return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: fmt.Sprintf("Webhook ID: %s already exists", payload.AutoUpdate.Webhook), Err: errWebhookIDAlreadyExists} @@ -266,12 +266,12 @@ func (handler *Handler) createComposeStackFromGitRepository(w http.ResponseWrite err = handler.clone(projectPath, payload.RepositoryURL, payload.RepositoryReferenceName, payload.RepositoryAuthentication, payload.RepositoryUsername, payload.RepositoryPassword) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to clone git repository", Err: err} + return httperror.InternalServerError("Unable to clone git repository", err) } commitID, err := handler.latestCommitID(payload.RepositoryURL, payload.RepositoryReferenceName, payload.RepositoryAuthentication, payload.RepositoryUsername, payload.RepositoryPassword) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to fetch git repository id", Err: err} + return httperror.InternalServerError("Unable to fetch git repository id", err) } stack.GitConfig.ConfigHash = commitID @@ -282,7 +282,7 @@ func (handler *Handler) createComposeStackFromGitRepository(w http.ResponseWrite err = handler.deployComposeStack(config, false) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: err.Error(), Err: err} + return httperror.InternalServerError(err.Error(), err) } if payload.AutoUpdate != nil && payload.AutoUpdate.Interval != "" { @@ -298,7 +298,7 @@ func (handler *Handler) createComposeStackFromGitRepository(w http.ResponseWrite err = handler.DataStore.Stack().Create(stack) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to persist the stack inside the database", Err: err} + return httperror.InternalServerError("Unable to persist the stack inside the database", err) } doCleanUp = false @@ -337,14 +337,14 @@ func decodeRequestForm(r *http.Request) (*composeStackFromFileUploadPayload, err 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 { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } payload.Name = handler.ComposeStackManager.NormalizeStackName(payload.Name) isUnique, err := handler.checkUniqueStackNameInDocker(endpoint, payload.Name, 0, false) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to check for name collision", Err: err} + return httperror.InternalServerError("Unable to check for name collision", err) } if !isUnique { @@ -356,7 +356,7 @@ func (handler *Handler) createComposeStackFromFileUpload(w http.ResponseWriter, if stack.Type != portainer.DockerComposeStack && stack.EndpointID == endpoint.ID { err := handler.checkAndCleanStackDupFromSwarm(w, r, endpoint, userID, &stack) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } } else { return stackExistsError(payload.Name) @@ -379,7 +379,7 @@ func (handler *Handler) createComposeStackFromFileUpload(w http.ResponseWriter, stackFolder := strconv.Itoa(int(stack.ID)) projectPath, err := handler.FileService.StoreStackFileFromBytes(stackFolder, stack.EntryPoint, payload.StackFileContent) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to persist Compose file on disk", Err: err} + return httperror.InternalServerError("Unable to persist Compose file on disk", err) } stack.ProjectPath = projectPath @@ -393,14 +393,14 @@ func (handler *Handler) createComposeStackFromFileUpload(w http.ResponseWriter, err = handler.deployComposeStack(config, false) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: err.Error(), Err: err} + return httperror.InternalServerError(err.Error(), err) } stack.CreatedBy = config.user.Username err = handler.DataStore.Stack().Create(stack) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to persist the stack inside the database", Err: err} + return httperror.InternalServerError("Unable to persist the stack inside the database", err) } doCleanUp = false @@ -418,17 +418,17 @@ type composeStackDeploymentConfig struct { func (handler *Handler) createComposeDeployConfig(r *http.Request, stack *portainer.Stack, endpoint *portainer.Endpoint) (*composeStackDeploymentConfig, *httperror.HandlerError) { securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return nil, &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve info from request context", Err: err} + return nil, httperror.InternalServerError("Unable to retrieve info from request context", err) } user, err := handler.DataStore.User().User(securityContext.UserID) if err != nil { - return nil, &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to load user information from the database", Err: err} + return nil, httperror.InternalServerError("Unable to load user information from the database", err) } registries, err := handler.DataStore.Registry().Registries() if err != nil { - return nil, &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve registries from the database", Err: err} + return nil, httperror.InternalServerError("Unable to retrieve registries from the database", err) } filteredRegistries := security.FilterRegistries(registries, user, securityContext.UserMemberships, endpoint.ID) diff --git a/api/http/handler/stacks/create_kubernetes_stack.go b/api/http/handler/stacks/create_kubernetes_stack.go index 87593b829..538a2e460 100644 --- a/api/http/handler/stacks/create_kubernetes_stack.go +++ b/api/http/handler/stacks/create_kubernetes_stack.go @@ -96,16 +96,16 @@ type createKubernetesStackResponse struct { func (handler *Handler) createKubernetesStackFromFileContent(w http.ResponseWriter, r *http.Request, endpoint *portainer.Endpoint, userID portainer.UserID) *httperror.HandlerError { var payload kubernetesStringDeploymentPayload if err := request.DecodeAndValidateJSONPayload(r, &payload); err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } user, err := handler.DataStore.User().User(userID) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to load user information from the database", Err: err} + return httperror.InternalServerError("Unable to load user information from the database", err) } isUnique, err := handler.checkUniqueStackNameInKubernetes(endpoint, payload.StackName, 0, payload.Namespace) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to check for name collision", Err: err} + return httperror.InternalServerError("Unable to check for name collision", err) } if !isUnique { return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: fmt.Sprintf("A stack with the name '%s' already exists", payload.StackName), Err: errStackAlreadyExists} @@ -133,7 +133,7 @@ func (handler *Handler) createKubernetesStackFromFileContent(w http.ResponseWrit fileType = "Compose" } errMsg := fmt.Sprintf("Unable to persist Kubernetes %s file on disk", fileType) - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: errMsg, Err: err} + return httperror.InternalServerError(errMsg, err) } stack.ProjectPath = projectPath @@ -148,12 +148,12 @@ func (handler *Handler) createKubernetesStackFromFileContent(w http.ResponseWrit }) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to deploy Kubernetes stack", Err: err} + return httperror.InternalServerError("Unable to deploy Kubernetes stack", err) } err = handler.DataStore.Stack().Create(stack) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to persist the Kubernetes stack inside the database", Err: err} + return httperror.InternalServerError("Unable to persist the Kubernetes stack inside the database", err) } resp := &createKubernetesStackResponse{ @@ -167,16 +167,16 @@ func (handler *Handler) createKubernetesStackFromFileContent(w http.ResponseWrit func (handler *Handler) createKubernetesStackFromGitRepository(w http.ResponseWriter, r *http.Request, endpoint *portainer.Endpoint, userID portainer.UserID) *httperror.HandlerError { var payload kubernetesGitDeploymentPayload if err := request.DecodeAndValidateJSONPayload(r, &payload); err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } user, err := handler.DataStore.User().User(userID) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to load user information from the database", Err: err} + return httperror.InternalServerError("Unable to load user information from the database", err) } isUnique, err := handler.checkUniqueStackNameInKubernetes(endpoint, payload.StackName, 0, payload.Namespace) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to check for name collision", Err: err} + return httperror.InternalServerError("Unable to check for name collision", err) } if !isUnique { return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: fmt.Sprintf("A stack with the name '%s' already exists", payload.StackName), Err: errStackAlreadyExists} @@ -186,7 +186,7 @@ func (handler *Handler) createKubernetesStackFromGitRepository(w http.ResponseWr if payload.AutoUpdate != nil && payload.AutoUpdate.Webhook != "" { isUnique, err := handler.checkUniqueWebhookID(payload.AutoUpdate.Webhook) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to check for webhook ID collision", Err: err} + return httperror.InternalServerError("Unable to check for webhook ID collision", err) } if !isUnique { return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: fmt.Sprintf("Webhook ID: %s already exists", payload.AutoUpdate.Webhook), Err: errWebhookIDAlreadyExists} @@ -229,7 +229,7 @@ func (handler *Handler) createKubernetesStackFromGitRepository(w http.ResponseWr commitID, err := handler.latestCommitID(payload.RepositoryURL, payload.RepositoryReferenceName, payload.RepositoryAuthentication, payload.RepositoryUsername, payload.RepositoryPassword) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to fetch git repository id", Err: err} + return httperror.InternalServerError("Unable to fetch git repository id", err) } stack.GitConfig.ConfigHash = commitID @@ -242,7 +242,7 @@ func (handler *Handler) createKubernetesStackFromGitRepository(w http.ResponseWr err = handler.GitService.CloneRepository(projectPath, payload.RepositoryURL, payload.RepositoryReferenceName, repositoryUsername, repositoryPassword) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Failed to clone git repository", Err: err} + return httperror.InternalServerError("Failed to clone git repository", err) } output, err := handler.deployKubernetesStack(user.ID, endpoint, stack, k.KubeAppLabels{ @@ -253,7 +253,7 @@ func (handler *Handler) createKubernetesStackFromGitRepository(w http.ResponseWr }) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to deploy Kubernetes stack", Err: err} + return httperror.InternalServerError("Unable to deploy Kubernetes stack", err) } if payload.AutoUpdate != nil && payload.AutoUpdate.Interval != "" { @@ -267,7 +267,7 @@ func (handler *Handler) createKubernetesStackFromGitRepository(w http.ResponseWr err = handler.DataStore.Stack().Create(stack) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to persist the stack inside the database", Err: err} + return httperror.InternalServerError("Unable to persist the stack inside the database", err) } resp := &createKubernetesStackResponse{ @@ -281,16 +281,16 @@ func (handler *Handler) createKubernetesStackFromGitRepository(w http.ResponseWr 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 { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } user, err := handler.DataStore.User().User(userID) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to load user information from the database", Err: err} + return httperror.InternalServerError("Unable to load user information from the database", err) } isUnique, err := handler.checkUniqueStackNameInKubernetes(endpoint, payload.StackName, 0, payload.Namespace) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to check for name collision", Err: err} + return httperror.InternalServerError("Unable to check for name collision", err) } if !isUnique { return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: fmt.Sprintf("A stack with the name '%s' already exists", payload.StackName), Err: errStackAlreadyExists} @@ -313,13 +313,13 @@ func (handler *Handler) createKubernetesStackFromManifestURL(w http.ResponseWrit var manifestContent []byte manifestContent, err = client.Get(payload.ManifestURL, 30) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve manifest from URL", Err: err} + return httperror.InternalServerError("Unable to retrieve manifest from URL", err) } stackFolder := strconv.Itoa(int(stack.ID)) projectPath, err := handler.FileService.StoreStackFileFromBytes(stackFolder, stack.EntryPoint, manifestContent) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to persist Kubernetes manifest file on disk", Err: err} + return httperror.InternalServerError("Unable to persist Kubernetes manifest file on disk", err) } stack.ProjectPath = projectPath @@ -333,12 +333,12 @@ func (handler *Handler) createKubernetesStackFromManifestURL(w http.ResponseWrit Kind: "url", }) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to deploy Kubernetes stack", Err: err} + return httperror.InternalServerError("Unable to deploy Kubernetes stack", err) } err = handler.DataStore.Stack().Create(stack) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to persist the Kubernetes stack inside the database", Err: err} + return httperror.InternalServerError("Unable to persist the Kubernetes stack inside the database", err) } doCleanUp = false diff --git a/api/http/handler/stacks/create_swarm_stack.go b/api/http/handler/stacks/create_swarm_stack.go index 606f59fcb..1b024fcc0 100644 --- a/api/http/handler/stacks/create_swarm_stack.go +++ b/api/http/handler/stacks/create_swarm_stack.go @@ -47,7 +47,7 @@ func (handler *Handler) createSwarmStackFromFileContent(w http.ResponseWriter, r var payload swarmStackFromFileContentPayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } payload.Name = handler.SwarmStackManager.NormalizeStackName(payload.Name) @@ -55,7 +55,7 @@ func (handler *Handler) createSwarmStackFromFileContent(w http.ResponseWriter, r isUnique, err := handler.checkUniqueStackNameInDocker(endpoint, payload.Name, 0, true) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to check for name collision", err} + return httperror.InternalServerError("Unable to check for name collision", err) } if !isUnique { return stackExistsError(payload.Name) @@ -78,7 +78,7 @@ func (handler *Handler) createSwarmStackFromFileContent(w http.ResponseWriter, r stackFolder := strconv.Itoa(int(stack.ID)) projectPath, err := handler.FileService.StoreStackFileFromBytes(stackFolder, stack.EntryPoint, []byte(payload.StackFileContent)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist Compose file on disk", err} + return httperror.InternalServerError("Unable to persist Compose file on disk", err) } stack.ProjectPath = projectPath @@ -92,14 +92,14 @@ func (handler *Handler) createSwarmStackFromFileContent(w http.ResponseWriter, r err = handler.deploySwarmStack(config) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, err.Error(), err} + return httperror.InternalServerError(err.Error(), err) } stack.CreatedBy = config.user.Username err = handler.DataStore.Stack().Create(stack) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist the stack inside the database", err} + return httperror.InternalServerError("Unable to persist the stack inside the database", err) } doCleanUp = false @@ -157,14 +157,14 @@ func (handler *Handler) createSwarmStackFromGitRepository(w http.ResponseWriter, var payload swarmStackFromGitRepositoryPayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } payload.Name = handler.SwarmStackManager.NormalizeStackName(payload.Name) isUnique, err := handler.checkUniqueStackNameInDocker(endpoint, payload.Name, 0, true) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to check for name collision", Err: err} + return httperror.InternalServerError("Unable to check for name collision", err) } if !isUnique { return stackExistsError(payload.Name) @@ -174,7 +174,7 @@ func (handler *Handler) createSwarmStackFromGitRepository(w http.ResponseWriter, if payload.AutoUpdate != nil && payload.AutoUpdate.Webhook != "" { isUnique, err := handler.checkUniqueWebhookID(payload.AutoUpdate.Webhook) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to check for webhook ID collision", Err: err} + return httperror.InternalServerError("Unable to check for webhook ID collision", err) } if !isUnique { return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: fmt.Sprintf("Webhook ID: %s already exists", payload.AutoUpdate.Webhook), Err: errWebhookIDAlreadyExists} @@ -217,12 +217,12 @@ func (handler *Handler) createSwarmStackFromGitRepository(w http.ResponseWriter, err = handler.clone(projectPath, payload.RepositoryURL, payload.RepositoryReferenceName, payload.RepositoryAuthentication, payload.RepositoryUsername, payload.RepositoryPassword) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to clone git repository", Err: err} + return httperror.InternalServerError("Unable to clone git repository", err) } commitID, err := handler.latestCommitID(payload.RepositoryURL, payload.RepositoryReferenceName, payload.RepositoryAuthentication, payload.RepositoryUsername, payload.RepositoryPassword) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to fetch git repository id", Err: err} + return httperror.InternalServerError("Unable to fetch git repository id", err) } stack.GitConfig.ConfigHash = commitID @@ -233,7 +233,7 @@ func (handler *Handler) createSwarmStackFromGitRepository(w http.ResponseWriter, err = handler.deploySwarmStack(config) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: err.Error(), Err: err} + return httperror.InternalServerError(err.Error(), err) } if payload.AutoUpdate != nil && payload.AutoUpdate.Interval != "" { @@ -249,7 +249,7 @@ func (handler *Handler) createSwarmStackFromGitRepository(w http.ResponseWriter, err = handler.DataStore.Stack().Create(stack) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to persist the stack inside the database", Err: err} + return httperror.InternalServerError("Unable to persist the stack inside the database", err) } doCleanUp = false @@ -295,7 +295,7 @@ func (handler *Handler) createSwarmStackFromFileUpload(w http.ResponseWriter, r payload := &swarmStackFromFileUploadPayload{} err := payload.Validate(r) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } payload.Name = handler.SwarmStackManager.NormalizeStackName(payload.Name) @@ -303,7 +303,7 @@ func (handler *Handler) createSwarmStackFromFileUpload(w http.ResponseWriter, r isUnique, err := handler.checkUniqueStackNameInDocker(endpoint, payload.Name, 0, true) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to check for name collision", err} + return httperror.InternalServerError("Unable to check for name collision", err) } if !isUnique { return stackExistsError(payload.Name) @@ -325,7 +325,7 @@ func (handler *Handler) createSwarmStackFromFileUpload(w http.ResponseWriter, r stackFolder := strconv.Itoa(int(stack.ID)) projectPath, err := handler.FileService.StoreStackFileFromBytes(stackFolder, stack.EntryPoint, []byte(payload.StackFileContent)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist Compose file on disk", err} + return httperror.InternalServerError("Unable to persist Compose file on disk", err) } stack.ProjectPath = projectPath @@ -339,14 +339,14 @@ func (handler *Handler) createSwarmStackFromFileUpload(w http.ResponseWriter, r err = handler.deploySwarmStack(config) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, err.Error(), err} + return httperror.InternalServerError(err.Error(), err) } stack.CreatedBy = config.user.Username err = handler.DataStore.Stack().Create(stack) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist the stack inside the database", err} + return httperror.InternalServerError("Unable to persist the stack inside the database", err) } doCleanUp = false @@ -365,17 +365,17 @@ type swarmStackDeploymentConfig struct { func (handler *Handler) createSwarmDeployConfig(r *http.Request, stack *portainer.Stack, endpoint *portainer.Endpoint, prune bool) (*swarmStackDeploymentConfig, *httperror.HandlerError) { securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return nil, &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return nil, httperror.InternalServerError("Unable to retrieve info from request context", err) } user, err := handler.DataStore.User().User(securityContext.UserID) if err != nil { - return nil, &httperror.HandlerError{http.StatusInternalServerError, "Unable to load user information from the database", err} + return nil, httperror.InternalServerError("Unable to load user information from the database", err) } registries, err := handler.DataStore.Registry().Registries() if err != nil { - return nil, &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve registries from the database", err} + return nil, httperror.InternalServerError("Unable to retrieve registries from the database", err) } filteredRegistries := security.FilterRegistries(registries, user, securityContext.UserMemberships, endpoint.ID) diff --git a/api/http/handler/stacks/stack_associate.go b/api/http/handler/stacks/stack_associate.go index adf8eca64..339273a46 100644 --- a/api/http/handler/stacks/stack_associate.go +++ b/api/http/handler/stacks/stack_associate.go @@ -33,44 +33,44 @@ import ( func (handler *Handler) stackAssociate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { stackID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid stack identifier route variable", err} + return httperror.BadRequest("Invalid stack identifier route variable", err) } endpointID, err := request.RetrieveNumericQueryParameter(r, "endpointId", false) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: endpointId", err} + return httperror.BadRequest("Invalid query parameter: endpointId", err) } swarmId, err := request.RetrieveQueryParameter(r, "swarmId", true) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: swarmId", err} + return httperror.BadRequest("Invalid query parameter: swarmId", err) } orphanedRunning, err := request.RetrieveBooleanQueryParameter(r, "orphanedRunning", false) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: orphanedRunning", err} + return httperror.BadRequest("Invalid query parameter: orphanedRunning", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } user, err := handler.DataStore.User().User(securityContext.UserID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to load user information from the database", err} + return httperror.InternalServerError("Unable to load user information from the database", err) } stack, err := handler.DataStore.Stack().Stack(portainer.StackID(stackID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a stack with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a stack with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a stack with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a stack with the specified identifier inside the database", err) } resourceControl, err := handler.DataStore.ResourceControl().ResourceControlByResourceIDAndType(stackutils.ResourceControlID(stack.EndpointID, stack.Name), portainer.StackResourceControl) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve a resource control associated to the stack", err} + return httperror.InternalServerError("Unable to retrieve a resource control associated to the stack", err) } if resourceControl != nil { @@ -78,24 +78,24 @@ func (handler *Handler) stackAssociate(w http.ResponseWriter, r *http.Request) * err = handler.DataStore.ResourceControl().UpdateResourceControl(resourceControl.ID, resourceControl) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist resource control changes inside the database", err} + return httperror.InternalServerError("Unable to persist resource control changes inside the database", err) } } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Unable to find an environment with the specified identifier inside the database", Err: err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to find an environment with the specified identifier inside the database", Err: err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } canManage, err := handler.userCanManageStacks(securityContext, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to verify user authorizations to validate stack deletion", Err: err} + return httperror.InternalServerError("Unable to verify user authorizations to validate stack deletion", err) } if !canManage { errMsg := "Stack management is disabled for non-admin users" - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: errMsg, Err: fmt.Errorf(errMsg)} + return httperror.Forbidden(errMsg, fmt.Errorf(errMsg)) } stack.EndpointID = portainer.EndpointID(endpointID) @@ -114,7 +114,7 @@ func (handler *Handler) stackAssociate(w http.ResponseWriter, r *http.Request) * err = handler.DataStore.Stack().UpdateStack(stack.ID, stack) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist the stack changes inside the database", err} + return httperror.InternalServerError("Unable to persist the stack changes inside the database", err) } stack.ResourceControl = resourceControl diff --git a/api/http/handler/stacks/stack_create.go b/api/http/handler/stacks/stack_create.go index 5f6f4afe5..566ed033f 100644 --- a/api/http/handler/stacks/stack_create.go +++ b/api/http/handler/stacks/stack_create.go @@ -55,48 +55,48 @@ func (handler *Handler) cleanUp(stack *portainer.Stack, doCleanUp *bool) error { func (handler *Handler) stackCreate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { stackType, err := request.RetrieveNumericQueryParameter(r, "type", false) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: type", err} + return httperror.BadRequest("Invalid query parameter: type", err) } method, err := request.RetrieveQueryParameter(r, "method", false) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: method", err} + return httperror.BadRequest("Invalid query parameter: method", err) } endpointID, err := request.RetrieveNumericQueryParameter(r, "endpointId", false) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: endpointId", err} + return httperror.BadRequest("Invalid query parameter: endpointId", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve user info from request context", Err: err} + return httperror.InternalServerError("Unable to retrieve user info from request context", err) } canManage, err := handler.userCanManageStacks(securityContext, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to verify user authorizations to validate stack deletion", Err: err} + return httperror.InternalServerError("Unable to verify user authorizations to validate stack deletion", err) } if !canManage { errMsg := "Stack creation is disabled for non-admin users" - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: errMsg, Err: errors.New(errMsg)} + return httperror.Forbidden(errMsg, errors.New(errMsg)) } err = handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access environment", err} + return httperror.Forbidden("Permission denied to access environment", err) } tokenData, err := security.RetrieveTokenData(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user details from authentication token", err} + return httperror.InternalServerError("Unable to retrieve user details from authentication token", err) } switch portainer.StackType(stackType) { @@ -108,7 +108,7 @@ func (handler *Handler) stackCreate(w http.ResponseWriter, r *http.Request) *htt return handler.createKubernetesStack(w, r, method, endpoint, tokenData.ID) } - return &httperror.HandlerError{http.StatusBadRequest, "Invalid value for query parameter: type. Value must be one of: 1 (Swarm stack) or 2 (Compose stack)", errors.New(request.ErrInvalidQueryParameter)} + return httperror.BadRequest("Invalid value for query parameter: type. Value must be one of: 1 (Swarm stack) or 2 (Compose stack)", errors.New(request.ErrInvalidQueryParameter)) } func (handler *Handler) createComposeStack(w http.ResponseWriter, r *http.Request, method string, endpoint *portainer.Endpoint, userID portainer.UserID) *httperror.HandlerError { @@ -122,7 +122,7 @@ func (handler *Handler) createComposeStack(w http.ResponseWriter, r *http.Reques return handler.createComposeStackFromFileUpload(w, r, endpoint, userID) } - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid value for query parameter: method. Value must be one of: string, repository or file", Err: errors.New(request.ErrInvalidQueryParameter)} + return httperror.BadRequest("Invalid value for query parameter: method. Value must be one of: string, repository or file", errors.New(request.ErrInvalidQueryParameter)) } func (handler *Handler) createSwarmStack(w http.ResponseWriter, r *http.Request, method string, endpoint *portainer.Endpoint, userID portainer.UserID) *httperror.HandlerError { @@ -135,7 +135,7 @@ func (handler *Handler) createSwarmStack(w http.ResponseWriter, r *http.Request, return handler.createSwarmStackFromFileUpload(w, r, endpoint, userID) } - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid value for query parameter: method. Value must be one of: string, repository or file", Err: errors.New(request.ErrInvalidQueryParameter)} + return httperror.BadRequest("Invalid value for query parameter: method. Value must be one of: string, repository or file", errors.New(request.ErrInvalidQueryParameter)) } func (handler *Handler) createKubernetesStack(w http.ResponseWriter, r *http.Request, method string, endpoint *portainer.Endpoint, userID portainer.UserID) *httperror.HandlerError { @@ -147,7 +147,7 @@ func (handler *Handler) createKubernetesStack(w http.ResponseWriter, r *http.Req case "url": return handler.createKubernetesStackFromManifestURL(w, r, endpoint, userID) } - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid value for query parameter: method. Value must be one of: string or repository", Err: errors.New(request.ErrInvalidQueryParameter)} + return httperror.BadRequest("Invalid value for query parameter: method. Value must be one of: string or repository", errors.New(request.ErrInvalidQueryParameter)) } func (handler *Handler) isValidStackFile(stackFileContent []byte, securitySettings *portainer.EndpointSecuritySettings) error { @@ -212,7 +212,7 @@ func (handler *Handler) decorateStackResponse(w http.ResponseWriter, stack *port isAdmin, err := handler.userIsAdmin(userID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to load user information from the database", err} + return httperror.InternalServerError("Unable to load user information from the database", err) } if isAdmin { @@ -223,7 +223,7 @@ func (handler *Handler) decorateStackResponse(w http.ResponseWriter, stack *port err = handler.DataStore.ResourceControl().Create(resourceControl) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist resource control inside the database", err} + return httperror.InternalServerError("Unable to persist resource control inside the database", err) } stack.ResourceControl = resourceControl diff --git a/api/http/handler/stacks/stack_delete.go b/api/http/handler/stacks/stack_delete.go index c38f4f0c3..d3bfccafa 100644 --- a/api/http/handler/stacks/stack_delete.go +++ b/api/http/handler/stacks/stack_delete.go @@ -38,12 +38,12 @@ import ( func (handler *Handler) stackDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { stackID, err := request.RetrieveRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid stack identifier route variable", Err: err} + return httperror.BadRequest("Invalid stack identifier route variable", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve info from request context", Err: err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } externalStack, _ := request.RetrieveBooleanQueryParameter(r, "external", true) @@ -53,63 +53,63 @@ func (handler *Handler) stackDelete(w http.ResponseWriter, r *http.Request) *htt id, err := strconv.Atoi(stackID) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid stack identifier route variable", Err: err} + return httperror.BadRequest("Invalid stack identifier route variable", err) } stack, err := handler.DataStore.Stack().Stack(portainer.StackID(id)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Unable to find a stack with the specified identifier inside the database", Err: err} + return httperror.NotFound("Unable to find a stack with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to find a stack with the specified identifier inside the database", Err: err} + return httperror.InternalServerError("Unable to find a stack with the specified identifier inside the database", err) } endpointID, err := request.RetrieveNumericQueryParameter(r, "endpointId", true) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid query parameter: endpointId", Err: err} + return httperror.BadRequest("Invalid query parameter: endpointId", err) } isOrphaned := portainer.EndpointID(endpointID) != stack.EndpointID if isOrphaned && !securityContext.IsAdmin { - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "Permission denied to remove orphaned stack", Err: errors.New("Permission denied to remove orphaned stack")} + return httperror.Forbidden("Permission denied to remove orphaned stack", errors.New("Permission denied to remove orphaned stack")) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Unable to find the endpoint associated to the stack inside the database", Err: err} + return httperror.NotFound("Unable to find the endpoint associated to the stack inside the database", err) } else if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to find the endpoint associated to the stack inside the database", Err: err} + return httperror.InternalServerError("Unable to find the endpoint associated to the stack inside the database", err) } resourceControl, err := handler.DataStore.ResourceControl().ResourceControlByResourceIDAndType(stackutils.ResourceControlID(stack.EndpointID, stack.Name), portainer.StackResourceControl) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve a resource control associated to the stack", Err: err} + return httperror.InternalServerError("Unable to retrieve a resource control associated to the stack", err) } if !isOrphaned { err = handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "Permission denied to access endpoint", Err: err} + return httperror.Forbidden("Permission denied to access endpoint", err) } if stack.Type == portainer.DockerSwarmStack || stack.Type == portainer.DockerComposeStack { access, err := handler.userCanAccessStack(securityContext, endpoint.ID, resourceControl) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to verify user authorizations to validate stack access", Err: err} + return httperror.InternalServerError("Unable to verify user authorizations to validate stack access", err) } if !access { - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "Access denied to resource", Err: httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Access denied to resource", httperrors.ErrResourceAccessDenied) } } } canManage, err := handler.userCanManageStacks(securityContext, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to verify user authorizations to validate stack deletion", Err: err} + return httperror.InternalServerError("Unable to verify user authorizations to validate stack deletion", err) } if !canManage { errMsg := "Stack deletion is disabled for non-admin users" - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: errMsg, Err: fmt.Errorf(errMsg)} + return httperror.Forbidden(errMsg, fmt.Errorf(errMsg)) } // stop scheduler updates of the stack before removal @@ -119,24 +119,24 @@ func (handler *Handler) stackDelete(w http.ResponseWriter, r *http.Request) *htt err = handler.deleteStack(securityContext.UserID, stack, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: err.Error(), Err: err} + return httperror.InternalServerError(err.Error(), err) } err = handler.DataStore.Stack().DeleteStack(portainer.StackID(id)) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to remove the stack from the database", Err: err} + return httperror.InternalServerError("Unable to remove the stack from the database", err) } if resourceControl != nil { err = handler.DataStore.ResourceControl().DeleteResourceControl(resourceControl.ID) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to remove the associated resource control from the database", Err: err} + return httperror.InternalServerError("Unable to remove the associated resource control from the database", err) } } err = handler.FileService.RemoveDirectory(stack.ProjectPath) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to remove stack files from disk", Err: err} + return httperror.InternalServerError("Unable to remove stack files from disk", err) } return response.Empty(w) @@ -145,7 +145,7 @@ func (handler *Handler) stackDelete(w http.ResponseWriter, r *http.Request) *htt func (handler *Handler) deleteExternalStack(r *http.Request, w http.ResponseWriter, stackName string, securityContext *security.RestrictedRequestContext) *httperror.HandlerError { endpointID, err := request.RetrieveNumericQueryParameter(r, "endpointId", false) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid query parameter: endpointId", Err: err} + return httperror.BadRequest("Invalid query parameter: endpointId", err) } if !securityContext.IsAdmin { @@ -154,22 +154,22 @@ func (handler *Handler) deleteExternalStack(r *http.Request, w http.ResponseWrit stack, err := handler.DataStore.Stack().StackByName(stackName) if err != nil && !handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to check for stack existence inside the database", Err: err} + return httperror.InternalServerError("Unable to check for stack existence inside the database", err) } if stack != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "A stack with this name exists inside the database. Cannot use external delete method", Err: errors.New("A tag already exists with this name")} + return httperror.BadRequest("A stack with this name exists inside the database. Cannot use external delete method", errors.New("A tag already exists with this name")) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Unable to find the endpoint associated to the stack inside the database", Err: err} + return httperror.NotFound("Unable to find the endpoint associated to the stack inside the database", err) } else if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to find the endpoint associated to the stack inside the database", Err: err} + return httperror.InternalServerError("Unable to find the endpoint associated to the stack inside the database", err) } err = handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "Permission denied to access endpoint", Err: err} + return httperror.Forbidden("Permission denied to access endpoint", err) } stack = &portainer.Stack{ @@ -179,7 +179,7 @@ func (handler *Handler) deleteExternalStack(r *http.Request, w http.ResponseWrit err = handler.deleteStack(securityContext.UserID, stack, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to delete stack", Err: err} + return httperror.InternalServerError("Unable to delete stack", err) } return response.Empty(w) diff --git a/api/http/handler/stacks/stack_file.go b/api/http/handler/stacks/stack_file.go index c338c1c0a..2b6a90ff3 100644 --- a/api/http/handler/stacks/stack_file.go +++ b/api/http/handler/stacks/stack_file.go @@ -36,64 +36,64 @@ type stackFileResponse struct { func (handler *Handler) stackFile(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { stackID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid stack identifier route variable", err} + return httperror.BadRequest("Invalid stack identifier route variable", err) } stack, err := handler.DataStore.Stack().Stack(portainer.StackID(stackID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a stack with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a stack with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a stack with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a stack with the specified identifier inside the database", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(stack.EndpointID) if handler.DataStore.IsErrObjectNotFound(err) { if !securityContext.IsAdmin { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } canManage, err := handler.userCanManageStacks(securityContext, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to verify user authorizations to validate stack deletion", Err: err} + return httperror.InternalServerError("Unable to verify user authorizations to validate stack deletion", err) } if !canManage { errMsg := "Stack management is disabled for non-admin users" - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: errMsg, Err: errors.New(errMsg)} + return httperror.Forbidden(errMsg, errors.New(errMsg)) } if endpoint != nil { err = handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access environment", err} + return httperror.Forbidden("Permission denied to access environment", err) } if stack.Type == portainer.DockerSwarmStack || stack.Type == portainer.DockerComposeStack { resourceControl, err := handler.DataStore.ResourceControl().ResourceControlByResourceIDAndType(stackutils.ResourceControlID(stack.EndpointID, stack.Name), portainer.StackResourceControl) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve a resource control associated to the stack", err} + return httperror.InternalServerError("Unable to retrieve a resource control associated to the stack", err) } access, err := handler.userCanAccessStack(securityContext, endpoint.ID, resourceControl) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to verify user authorizations to validate stack access", err} + return httperror.InternalServerError("Unable to verify user authorizations to validate stack access", err) } if !access { - return &httperror.HandlerError{http.StatusForbidden, "Access denied to resource", httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Access denied to resource", httperrors.ErrResourceAccessDenied) } } } stackFileContent, err := handler.FileService.GetFileContent(stack.ProjectPath, stack.EntryPoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve Compose file from disk", err} + return httperror.InternalServerError("Unable to retrieve Compose file from disk", err) } return response.JSON(w, &stackFileResponse{StackFileContent: string(stackFileContent)}) diff --git a/api/http/handler/stacks/stack_inspect.go b/api/http/handler/stacks/stack_inspect.go index eda80f617..df0fb8adc 100644 --- a/api/http/handler/stacks/stack_inspect.go +++ b/api/http/handler/stacks/stack_inspect.go @@ -31,57 +31,57 @@ import ( func (handler *Handler) stackInspect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { stackID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid stack identifier route variable", err} + return httperror.BadRequest("Invalid stack identifier route variable", err) } stack, err := handler.DataStore.Stack().Stack(portainer.StackID(stackID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a stack with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a stack with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a stack with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a stack with the specified identifier inside the database", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(stack.EndpointID) if handler.DataStore.IsErrObjectNotFound(err) { if !securityContext.IsAdmin { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } canManage, err := handler.userCanManageStacks(securityContext, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to verify user authorizations to validate stack deletion", Err: err} + return httperror.InternalServerError("Unable to verify user authorizations to validate stack deletion", err) } if !canManage { errMsg := "Stack management is disabled for non-admin users" - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: errMsg, Err: errors.New(errMsg)} + return httperror.Forbidden(errMsg, errors.New(errMsg)) } if endpoint != nil { err = handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access environment", err} + return httperror.Forbidden("Permission denied to access environment", err) } if stack.Type == portainer.DockerSwarmStack || stack.Type == portainer.DockerComposeStack { resourceControl, err := handler.DataStore.ResourceControl().ResourceControlByResourceIDAndType(stackutils.ResourceControlID(stack.EndpointID, stack.Name), portainer.StackResourceControl) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve a resource control associated to the stack", err} + return httperror.InternalServerError("Unable to retrieve a resource control associated to the stack", err) } access, err := handler.userCanAccessStack(securityContext, endpoint.ID, resourceControl) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to verify user authorizations to validate stack access", err} + return httperror.InternalServerError("Unable to verify user authorizations to validate stack access", err) } if !access { - return &httperror.HandlerError{http.StatusForbidden, "Access denied to resource", httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Access denied to resource", httperrors.ErrResourceAccessDenied) } if resourceControl != nil { diff --git a/api/http/handler/stacks/stack_list.go b/api/http/handler/stacks/stack_list.go index 9b03776f9..24ab99bfb 100644 --- a/api/http/handler/stacks/stack_list.go +++ b/api/http/handler/stacks/stack_list.go @@ -38,40 +38,40 @@ func (handler *Handler) stackList(w http.ResponseWriter, r *http.Request) *httpe var filters stackListOperationFilters err := request.RetrieveJSONQueryParameter(r, "filters", &filters, true) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: filters", err} + return httperror.BadRequest("Invalid query parameter: filters", err) } endpoints, err := handler.DataStore.Endpoint().Endpoints() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve environments from database", err} + return httperror.InternalServerError("Unable to retrieve environments from database", err) } stacks, err := handler.DataStore.Stack().Stacks() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve stacks from the database", err} + return httperror.InternalServerError("Unable to retrieve stacks from the database", err) } stacks = filterStacks(stacks, &filters, endpoints) resourceControls, err := handler.DataStore.ResourceControl().ResourceControls() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve resource controls from the database", err} + return httperror.InternalServerError("Unable to retrieve resource controls from the database", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } stacks = authorization.DecorateStacks(stacks, resourceControls) if !securityContext.IsAdmin { if filters.IncludeOrphanedStacks { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access orphaned stacks", httperrors.ErrUnauthorized} + return httperror.Forbidden("Permission denied to access orphaned stacks", httperrors.ErrUnauthorized) } user, err := handler.DataStore.User().User(securityContext.UserID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user information from the database", err} + return httperror.InternalServerError("Unable to retrieve user information from the database", err) } userTeamIDs := make([]portainer.TeamID, 0) diff --git a/api/http/handler/stacks/stack_migrate.go b/api/http/handler/stacks/stack_migrate.go index 795c1e8c8..379fe97f5 100644 --- a/api/http/handler/stacks/stack_migrate.go +++ b/api/http/handler/stacks/stack_migrate.go @@ -50,63 +50,63 @@ func (payload *stackMigratePayload) Validate(r *http.Request) error { func (handler *Handler) stackMigrate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { stackID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid stack identifier route variable", Err: err} + return httperror.BadRequest("Invalid stack identifier route variable", err) } var payload stackMigratePayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } stack, err := handler.DataStore.Stack().Stack(portainer.StackID(stackID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Unable to find a stack with the specified identifier inside the database", Err: err} + return httperror.NotFound("Unable to find a stack with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to find a stack with the specified identifier inside the database", Err: err} + return httperror.InternalServerError("Unable to find a stack with the specified identifier inside the database", err) } if stack.Type == portainer.KubernetesStack { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Migrating a kubernetes stack is not supported", Err: err} + return httperror.BadRequest("Migrating a kubernetes stack is not supported", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(stack.EndpointID) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Unable to find an endpoint with the specified identifier inside the database", Err: err} + return httperror.NotFound("Unable to find an endpoint with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to find an endpoint with the specified identifier inside the database", Err: err} + return httperror.InternalServerError("Unable to find an endpoint with the specified identifier inside the database", err) } err = handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "Permission denied to access endpoint", Err: err} + return httperror.Forbidden("Permission denied to access endpoint", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve info from request context", Err: err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } canManage, err := handler.userCanManageStacks(securityContext, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to verify user authorizations to validate stack deletion", Err: err} + return httperror.InternalServerError("Unable to verify user authorizations to validate stack deletion", err) } if !canManage { errMsg := "Stack migration is disabled for non-admin users" - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: errMsg, Err: errors.New(errMsg)} + return httperror.Forbidden(errMsg, errors.New(errMsg)) } resourceControl, err := handler.DataStore.ResourceControl().ResourceControlByResourceIDAndType(stackutils.ResourceControlID(stack.EndpointID, stack.Name), portainer.StackResourceControl) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve a resource control associated to the stack", Err: err} + return httperror.InternalServerError("Unable to retrieve a resource control associated to the stack", err) } access, err := handler.userCanAccessStack(securityContext, endpoint.ID, resourceControl) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to verify user authorizations to validate stack access", Err: err} + return httperror.InternalServerError("Unable to verify user authorizations to validate stack access", err) } if !access { - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "Access denied to resource", Err: httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Access denied to resource", httperrors.ErrResourceAccessDenied) } // TODO: this is a work-around for stacks created with Portainer version >= 1.17.1 @@ -114,7 +114,7 @@ func (handler *Handler) stackMigrate(w http.ResponseWriter, r *http.Request) *ht // can use the optional EndpointID query parameter to associate a valid environment(endpoint) identifier to the stack. endpointID, err := request.RetrieveNumericQueryParameter(r, "endpointId", true) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid query parameter: endpointId", Err: err} + return httperror.BadRequest("Invalid query parameter: endpointId", err) } if endpointID != int(stack.EndpointID) { stack.EndpointID = portainer.EndpointID(endpointID) @@ -122,9 +122,9 @@ func (handler *Handler) stackMigrate(w http.ResponseWriter, r *http.Request) *ht targetEndpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(payload.EndpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Unable to find an endpoint with the specified identifier inside the database", Err: err} + return httperror.NotFound("Unable to find an endpoint with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to find an endpoint with the specified identifier inside the database", Err: err} + return httperror.InternalServerError("Unable to find an endpoint with the specified identifier inside the database", err) } stack.EndpointID = portainer.EndpointID(payload.EndpointID) @@ -139,7 +139,7 @@ func (handler *Handler) stackMigrate(w http.ResponseWriter, r *http.Request) *ht isUnique, err := handler.checkUniqueStackNameInDocker(targetEndpoint, stack.Name, stack.ID, stack.SwarmID != "") if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to check for name collision", Err: err} + return httperror.InternalServerError("Unable to check for name collision", err) } if !isUnique { @@ -156,20 +156,20 @@ func (handler *Handler) stackMigrate(w http.ResponseWriter, r *http.Request) *ht stack.Name = oldName err = handler.deleteStack(securityContext.UserID, stack, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: err.Error(), Err: err} + return httperror.InternalServerError(err.Error(), 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} + return httperror.InternalServerError("Unable to persist the stack changes inside the database", err) } if resourceControl != nil { resourceControl.ResourceID = stackutils.ResourceControlID(stack.EndpointID, stack.Name) err := handler.DataStore.ResourceControl().UpdateResourceControl(resourceControl.ID, resourceControl) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist the resource control changes", err} + return httperror.InternalServerError("Unable to persist the resource control changes", err) } } @@ -196,7 +196,7 @@ func (handler *Handler) migrateComposeStack(r *http.Request, stack *portainer.St err := handler.deployComposeStack(config, false) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: err.Error(), Err: err} + return httperror.InternalServerError(err.Error(), err) } return nil @@ -210,7 +210,7 @@ func (handler *Handler) migrateSwarmStack(r *http.Request, stack *portainer.Stac err := handler.deploySwarmStack(config) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: err.Error(), Err: err} + return httperror.InternalServerError(err.Error(), err) } return nil diff --git a/api/http/handler/stacks/stack_start.go b/api/http/handler/stacks/stack_start.go index caf1f948b..f93e1dce6 100644 --- a/api/http/handler/stacks/stack_start.go +++ b/api/http/handler/stacks/stack_start.go @@ -33,49 +33,49 @@ import ( func (handler *Handler) stackStart(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { stackID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid stack identifier route variable", Err: err} + return httperror.BadRequest("Invalid stack identifier route variable", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve info from request context", Err: err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } stack, err := handler.DataStore.Stack().Stack(portainer.StackID(stackID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Unable to find a stack with the specified identifier inside the database", Err: err} + return httperror.NotFound("Unable to find a stack with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to find a stack with the specified identifier inside the database", Err: err} + return httperror.InternalServerError("Unable to find a stack with the specified identifier inside the database", err) } if stack.Type == portainer.KubernetesStack { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Starting a kubernetes stack is not supported", Err: err} + return httperror.BadRequest("Starting a kubernetes stack is not supported", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(stack.EndpointID) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Unable to find an endpoint with the specified identifier inside the database", Err: err} + return httperror.NotFound("Unable to find an endpoint with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to find an endpoint with the specified identifier inside the database", Err: err} + return httperror.InternalServerError("Unable to find an endpoint with the specified identifier inside the database", err) } err = handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "Permission denied to access endpoint", Err: err} + return httperror.Forbidden("Permission denied to access endpoint", err) } canManage, err := handler.userCanManageStacks(securityContext, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to verify user authorizations to validate stack deletion", Err: err} + return httperror.InternalServerError("Unable to verify user authorizations to validate stack deletion", err) } if !canManage { errMsg := "Stack management is disabled for non-admin users" - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: errMsg, Err: errors.New(errMsg)} + return httperror.Forbidden(errMsg, errors.New(errMsg)) } isUnique, err := handler.checkUniqueStackNameInDocker(endpoint, stack.Name, stack.ID, stack.SwarmID != "") if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to check for name collision", Err: err} + return httperror.InternalServerError("Unable to check for name collision", err) } if !isUnique { errorMessage := fmt.Sprintf("A stack with the name '%s' is already running", stack.Name) @@ -84,19 +84,19 @@ func (handler *Handler) stackStart(w http.ResponseWriter, r *http.Request) *http resourceControl, err := handler.DataStore.ResourceControl().ResourceControlByResourceIDAndType(stackutils.ResourceControlID(stack.EndpointID, stack.Name), portainer.StackResourceControl) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve a resource control associated to the stack", Err: err} + return httperror.InternalServerError("Unable to retrieve a resource control associated to the stack", err) } access, err := handler.userCanAccessStack(securityContext, endpoint.ID, resourceControl) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to verify user authorizations to validate stack access", Err: err} + return httperror.InternalServerError("Unable to verify user authorizations to validate stack access", err) } if !access { - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "Access denied to resource", Err: httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Access denied to resource", httperrors.ErrResourceAccessDenied) } if stack.Status == portainer.StackStatusActive { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Stack is already active", Err: errors.New("Stack is already active")} + return httperror.BadRequest("Stack is already active", errors.New("Stack is already active")) } if stack.AutoUpdate != nil && stack.AutoUpdate.Interval != "" { @@ -112,13 +112,13 @@ func (handler *Handler) stackStart(w http.ResponseWriter, r *http.Request) *http err = handler.startStack(stack, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to start stack", Err: err} + return httperror.InternalServerError("Unable to start stack", err) } stack.Status = portainer.StackStatusActive err = handler.DataStore.Stack().UpdateStack(stack.ID, stack) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to update stack status", Err: err} + return httperror.InternalServerError("Unable to update stack status", err) } if stack.GitConfig != nil && stack.GitConfig.Authentication != nil && stack.GitConfig.Authentication.Password != "" { diff --git a/api/http/handler/stacks/stack_stop.go b/api/http/handler/stacks/stack_stop.go index 8e2fdb5e1..175189db1 100644 --- a/api/http/handler/stacks/stack_stop.go +++ b/api/http/handler/stacks/stack_stop.go @@ -31,61 +31,61 @@ import ( func (handler *Handler) stackStop(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { stackID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid stack identifier route variable", err} + return httperror.BadRequest("Invalid stack identifier route variable", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } stack, err := handler.DataStore.Stack().Stack(portainer.StackID(stackID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a stack with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a stack with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a stack with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a stack with the specified identifier inside the database", err) } if stack.Type == portainer.KubernetesStack { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Stopping a kubernetes stack is not supported", Err: err} + return httperror.BadRequest("Stopping a kubernetes stack is not supported", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(stack.EndpointID) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } err = handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access environment", err} + return httperror.Forbidden("Permission denied to access environment", err) } resourceControl, err := handler.DataStore.ResourceControl().ResourceControlByResourceIDAndType(stackutils.ResourceControlID(stack.EndpointID, stack.Name), portainer.StackResourceControl) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve a resource control associated to the stack", err} + return httperror.InternalServerError("Unable to retrieve a resource control associated to the stack", err) } access, err := handler.userCanAccessStack(securityContext, endpoint.ID, resourceControl) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to verify user authorizations to validate stack access", err} + return httperror.InternalServerError("Unable to verify user authorizations to validate stack access", err) } if !access { - return &httperror.HandlerError{http.StatusForbidden, "Access denied to resource", httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Access denied to resource", httperrors.ErrResourceAccessDenied) } canManage, err := handler.userCanManageStacks(securityContext, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to verify user authorizations to validate stack deletion", Err: err} + return httperror.InternalServerError("Unable to verify user authorizations to validate stack deletion", err) } if !canManage { errMsg := "Stack management is disabled for non-admin users" - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: errMsg, Err: errors.New(errMsg)} + return httperror.Forbidden(errMsg, errors.New(errMsg)) } if stack.Status == portainer.StackStatusInactive { - return &httperror.HandlerError{http.StatusBadRequest, "Stack is already inactive", errors.New("Stack is already inactive")} + return httperror.BadRequest("Stack is already inactive", errors.New("Stack is already inactive")) } // stop scheduler updates of the stack before stopping @@ -96,13 +96,13 @@ func (handler *Handler) stackStop(w http.ResponseWriter, r *http.Request) *httpe err = handler.stopStack(stack, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to stop stack", err} + return httperror.InternalServerError("Unable to stop stack", err) } stack.Status = portainer.StackStatusInactive err = handler.DataStore.Stack().UpdateStack(stack.ID, stack) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to update stack status", err} + return httperror.InternalServerError("Unable to update stack status", err) } if stack.GitConfig != nil && stack.GitConfig.Authentication != nil && stack.GitConfig.Authentication.Password != "" { diff --git a/api/http/handler/stacks/stack_update.go b/api/http/handler/stacks/stack_update.go index 6bd60de74..bef1115c5 100644 --- a/api/http/handler/stacks/stack_update.go +++ b/api/http/handler/stacks/stack_update.go @@ -69,14 +69,14 @@ func (payload *updateSwarmStackPayload) Validate(r *http.Request) error { func (handler *Handler) stackUpdate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { stackID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid stack identifier route variable", err} + return httperror.BadRequest("Invalid stack identifier route variable", err) } stack, err := handler.DataStore.Stack().Stack(portainer.StackID(stackID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Unable to find a stack with the specified identifier inside the database", Err: err} + return httperror.NotFound("Unable to find a stack with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to find a stack with the specified identifier inside the database", Err: err} + return httperror.InternalServerError("Unable to find a stack with the specified identifier inside the database", err) } // TODO: this is a work-around for stacks created with Portainer version >= 1.17.1 @@ -84,7 +84,7 @@ func (handler *Handler) stackUpdate(w http.ResponseWriter, r *http.Request) *htt // can use the optional EndpointID query parameter to associate a valid environment(endpoint) identifier to the stack. endpointID, err := request.RetrieveNumericQueryParameter(r, "endpointId", true) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid query parameter: endpointId", Err: err} + return httperror.BadRequest("Invalid query parameter: endpointId", err) } if endpointID != int(stack.EndpointID) { stack.EndpointID = portainer.EndpointID(endpointID) @@ -92,19 +92,19 @@ func (handler *Handler) stackUpdate(w http.ResponseWriter, r *http.Request) *htt endpoint, err := handler.DataStore.Endpoint().Endpoint(stack.EndpointID) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Unable to find the environment associated to the stack inside the database", Err: err} + return httperror.NotFound("Unable to find the environment associated to the stack inside the database", err) } else if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to find the environment associated to the stack inside the database", Err: err} + return httperror.InternalServerError("Unable to find the environment associated to the stack inside the database", err) } err = handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "Permission denied to access environment", Err: err} + return httperror.Forbidden("Permission denied to access environment", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve info from request context", Err: err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } //only check resource control when it is a DockerSwarmStack or a DockerComposeStack @@ -112,25 +112,25 @@ func (handler *Handler) stackUpdate(w http.ResponseWriter, r *http.Request) *htt resourceControl, err := handler.DataStore.ResourceControl().ResourceControlByResourceIDAndType(stackutils.ResourceControlID(stack.EndpointID, stack.Name), portainer.StackResourceControl) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve a resource control associated to the stack", Err: err} + return httperror.InternalServerError("Unable to retrieve a resource control associated to the stack", err) } access, err := handler.userCanAccessStack(securityContext, endpoint.ID, resourceControl) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to verify user authorizations to validate stack access", Err: err} + return httperror.InternalServerError("Unable to verify user authorizations to validate stack access", err) } if !access { - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "Access denied to resource", Err: httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Access denied to resource", httperrors.ErrResourceAccessDenied) } } canManage, err := handler.userCanManageStacks(securityContext, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to verify user authorizations to validate stack deletion", Err: err} + return httperror.InternalServerError("Unable to verify user authorizations to validate stack deletion", err) } if !canManage { errMsg := "Stack editing is disabled for non-admin users" - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: errMsg, Err: errors.New(errMsg)} + return httperror.Forbidden(errMsg, errors.New(errMsg)) } updateError := handler.updateAndDeployStack(r, stack, endpoint) @@ -140,7 +140,7 @@ func (handler *Handler) stackUpdate(w http.ResponseWriter, r *http.Request) *htt user, err := handler.DataStore.User().User(securityContext.UserID) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Cannot find context user", Err: errors.Wrap(err, "failed to fetch the user")} + return httperror.BadRequest("Cannot find context user", errors.Wrap(err, "failed to fetch the user")) } stack.UpdatedBy = user.Username stack.UpdateDate = time.Now().Unix() @@ -148,7 +148,7 @@ func (handler *Handler) stackUpdate(w http.ResponseWriter, r *http.Request) *htt 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} + return httperror.InternalServerError("Unable to persist the stack changes inside the database", err) } if stack.GitConfig != nil && stack.GitConfig.Authentication != nil && stack.GitConfig.Authentication.Password != "" { @@ -167,7 +167,7 @@ func (handler *Handler) updateAndDeployStack(r *http.Request, stack *portainer.S } else if stack.Type == portainer.KubernetesStack { return handler.updateKubernetesStack(r, stack, endpoint) } else { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unsupported stack", Err: errors.Errorf("unsupported stack type: %v", stack.Type)} + return httperror.InternalServerError("Unsupported stack", errors.Errorf("unsupported stack type: %v", stack.Type)) } } @@ -184,7 +184,7 @@ func (handler *Handler) updateComposeStack(r *http.Request, stack *portainer.Sta var payload updateComposeStackPayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } stack.Env = payload.Env @@ -196,7 +196,7 @@ func (handler *Handler) updateComposeStack(r *http.Request, stack *portainer.Sta log.Printf("[WARN] [stack,update] [message: rollback stack file error] [err: %s]", rollbackErr) } - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to persist updated Compose file on disk", Err: err} + return httperror.InternalServerError("Unable to persist updated Compose file on disk", err) } config, configErr := handler.createComposeDeployConfig(r, stack, endpoint) @@ -214,7 +214,7 @@ func (handler *Handler) updateComposeStack(r *http.Request, stack *portainer.Sta log.Printf("[WARN] [stack,update] [message: rollback stack file error] [err: %s]", rollbackErr) } - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: err.Error(), Err: err} + return httperror.InternalServerError(err.Error(), err) } handler.FileService.RemoveStackFileBackup(stackFolder, stack.EntryPoint) @@ -235,7 +235,7 @@ func (handler *Handler) updateSwarmStack(r *http.Request, stack *portainer.Stack var payload updateSwarmStackPayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } stack.Env = payload.Env @@ -247,7 +247,7 @@ func (handler *Handler) updateSwarmStack(r *http.Request, stack *portainer.Stack log.Printf("[WARN] [swarm,stack,update] [message: rollback stack file error] [err: %s]", rollbackErr) } - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to persist updated Compose file on disk", Err: err} + return httperror.InternalServerError("Unable to persist updated Compose file on disk", err) } config, configErr := handler.createSwarmDeployConfig(r, stack, endpoint, payload.Prune) @@ -265,7 +265,7 @@ func (handler *Handler) updateSwarmStack(r *http.Request, stack *portainer.Stack log.Printf("[WARN] [swarm,stack,update] [message: rollback stack file error] [err: %s]", rollbackErr) } - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: err.Error(), Err: err} + return httperror.InternalServerError(err.Error(), err) } handler.FileService.RemoveStackFileBackup(stackFolder, stack.EntryPoint) diff --git a/api/http/handler/stacks/stack_update_git.go b/api/http/handler/stacks/stack_update_git.go index 80589f0a9..69cb218f4 100644 --- a/api/http/handler/stacks/stack_update_git.go +++ b/api/http/handler/stacks/stack_update_git.go @@ -53,23 +53,23 @@ func (payload *stackGitUpdatePayload) Validate(r *http.Request) error { func (handler *Handler) stackUpdateGit(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { stackID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid stack identifier route variable", Err: err} + return httperror.BadRequest("Invalid stack identifier route variable", err) } var payload stackGitUpdatePayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } stack, err := handler.DataStore.Stack().Stack(portainer.StackID(stackID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Unable to find a stack with the specified identifier inside the database", Err: err} + return httperror.NotFound("Unable to find a stack with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to find a stack with the specified identifier inside the database", Err: err} + return httperror.InternalServerError("Unable to find a stack with the specified identifier inside the database", err) } else if stack.GitConfig == nil { msg := "No Git config in the found stack" - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: msg, Err: errors.New(msg)} + return httperror.InternalServerError(msg, errors.New(msg)) } // TODO: this is a work-around for stacks created with Portainer version >= 1.17.1 @@ -77,7 +77,7 @@ func (handler *Handler) stackUpdateGit(w http.ResponseWriter, r *http.Request) * // can use the optional EndpointID query parameter to associate a valid environment(endpoint) identifier to the stack. endpointID, err := request.RetrieveNumericQueryParameter(r, "endpointId", true) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid query parameter: endpointId", Err: err} + return httperror.BadRequest("Invalid query parameter: endpointId", err) } if endpointID != int(stack.EndpointID) { stack.EndpointID = portainer.EndpointID(endpointID) @@ -85,48 +85,48 @@ func (handler *Handler) stackUpdateGit(w http.ResponseWriter, r *http.Request) * endpoint, err := handler.DataStore.Endpoint().Endpoint(stack.EndpointID) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Unable to find the environment associated to the stack inside the database", Err: err} + return httperror.NotFound("Unable to find the environment associated to the stack inside the database", err) } else if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to find the environment associated to the stack inside the database", Err: err} + return httperror.InternalServerError("Unable to find the environment associated to the stack inside the database", err) } err = handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "Permission denied to access environment", Err: err} + return httperror.Forbidden("Permission denied to access environment", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve info from request context", Err: err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } user, err := handler.DataStore.User().User(securityContext.UserID) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Cannot find context user", Err: errors.Wrap(err, "failed to fetch the user")} + return httperror.BadRequest("Cannot find context user", errors.Wrap(err, "failed to fetch the user")) } if stack.Type == portainer.DockerSwarmStack || stack.Type == portainer.DockerComposeStack { resourceControl, err := handler.DataStore.ResourceControl().ResourceControlByResourceIDAndType(stackutils.ResourceControlID(stack.EndpointID, stack.Name), portainer.StackResourceControl) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve a resource control associated to the stack", Err: err} + return httperror.InternalServerError("Unable to retrieve a resource control associated to the stack", err) } access, err := handler.userCanAccessStack(securityContext, endpoint.ID, resourceControl) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to verify user authorizations to validate stack access", Err: err} + return httperror.InternalServerError("Unable to verify user authorizations to validate stack access", err) } if !access { - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "Access denied to resource", Err: httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Access denied to resource", httperrors.ErrResourceAccessDenied) } } canManage, err := handler.userCanManageStacks(securityContext, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to verify user authorizations to validate stack deletion", Err: err} + return httperror.InternalServerError("Unable to verify user authorizations to validate stack deletion", err) } if !canManage { errMsg := "Stack editing is disabled for non-admin users" - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: errMsg, Err: errors.New(errMsg)} + return httperror.Forbidden(errMsg, errors.New(errMsg)) } //stop the autoupdate job if there is any @@ -158,7 +158,7 @@ func (handler *Handler) stackUpdateGit(w http.ResponseWriter, r *http.Request) * } _, err = handler.GitService.LatestCommitID(stack.GitConfig.URL, stack.GitConfig.ReferenceName, stack.GitConfig.Authentication.Username, stack.GitConfig.Authentication.Password) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to fetch git repository", Err: err} + return httperror.InternalServerError("Unable to fetch git repository", err) } } else { stack.GitConfig.Authentication = nil @@ -176,7 +176,7 @@ func (handler *Handler) stackUpdateGit(w http.ResponseWriter, r *http.Request) * //save the updated stack to DB 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} + return httperror.InternalServerError("Unable to persist the stack changes inside the database", err) } if stack.GitConfig != nil && stack.GitConfig.Authentication != nil && stack.GitConfig.Authentication.Password != "" { diff --git a/api/http/handler/stacks/stack_update_git_redeploy.go b/api/http/handler/stacks/stack_update_git_redeploy.go index ca85f4e30..f1f8badfc 100644 --- a/api/http/handler/stacks/stack_update_git_redeploy.go +++ b/api/http/handler/stacks/stack_update_git_redeploy.go @@ -52,18 +52,18 @@ func (payload *stackGitRedployPayload) Validate(r *http.Request) error { func (handler *Handler) stackGitRedeploy(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { stackID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid stack identifier route variable", Err: err} + return httperror.BadRequest("Invalid stack identifier route variable", err) } stack, err := handler.DataStore.Stack().Stack(portainer.StackID(stackID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Unable to find a stack with the specified identifier inside the database", Err: err} + return httperror.NotFound("Unable to find a stack with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to find a stack with the specified identifier inside the database", Err: err} + return httperror.InternalServerError("Unable to find a stack with the specified identifier inside the database", err) } if stack.GitConfig == nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Stack is not created from git", Err: err} + return httperror.BadRequest("Stack is not created from git", err) } // TODO: this is a work-around for stacks created with Portainer version >= 1.17.1 @@ -71,7 +71,7 @@ func (handler *Handler) stackGitRedeploy(w http.ResponseWriter, r *http.Request) // can use the optional EndpointID query parameter to associate a valid environment(endpoint) identifier to the stack. endpointID, err := request.RetrieveNumericQueryParameter(r, "endpointId", true) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid query parameter: endpointId", Err: err} + return httperror.BadRequest("Invalid query parameter: endpointId", err) } if endpointID != int(stack.EndpointID) { stack.EndpointID = portainer.EndpointID(endpointID) @@ -79,19 +79,19 @@ func (handler *Handler) stackGitRedeploy(w http.ResponseWriter, r *http.Request) endpoint, err := handler.DataStore.Endpoint().Endpoint(stack.EndpointID) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Unable to find the environment associated to the stack inside the database", Err: err} + return httperror.NotFound("Unable to find the environment associated to the stack inside the database", err) } else if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to find the environment associated to the stack inside the database", Err: err} + return httperror.InternalServerError("Unable to find the environment associated to the stack inside the database", err) } err = handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "Permission denied to access environment", Err: err} + return httperror.Forbidden("Permission denied to access environment", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve info from request context", Err: err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } //only check resource control when it is a DockerSwarmStack or a DockerComposeStack @@ -99,31 +99,31 @@ func (handler *Handler) stackGitRedeploy(w http.ResponseWriter, r *http.Request) resourceControl, err := handler.DataStore.ResourceControl().ResourceControlByResourceIDAndType(stackutils.ResourceControlID(stack.EndpointID, stack.Name), portainer.StackResourceControl) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve a resource control associated to the stack", Err: err} + return httperror.InternalServerError("Unable to retrieve a resource control associated to the stack", err) } access, err := handler.userCanAccessStack(securityContext, endpoint.ID, resourceControl) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to verify user authorizations to validate stack access", Err: err} + return httperror.InternalServerError("Unable to verify user authorizations to validate stack access", err) } if !access { - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "Access denied to resource", Err: httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Access denied to resource", httperrors.ErrResourceAccessDenied) } } canManage, err := handler.userCanManageStacks(securityContext, endpoint) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to verify user authorizations to validate stack deletion", Err: err} + return httperror.InternalServerError("Unable to verify user authorizations to validate stack deletion", err) } if !canManage { errMsg := "Stack management is disabled for non-admin users" - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: errMsg, Err: errors.New(errMsg)} + return httperror.Forbidden(errMsg, errors.New(errMsg)) } var payload stackGitRedployPayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } stack.GitConfig.ReferenceName = payload.RepositoryReferenceName @@ -137,7 +137,7 @@ func (handler *Handler) stackGitRedeploy(w http.ResponseWriter, r *http.Request) backupProjectPath := fmt.Sprintf("%s-old", stack.ProjectPath) err = filesystem.MoveDirectory(stack.ProjectPath, backupProjectPath) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to move git repository directory", Err: err} + return httperror.InternalServerError("Unable to move git repository directory", err) } repositoryUsername := "" @@ -157,7 +157,7 @@ func (handler *Handler) stackGitRedeploy(w http.ResponseWriter, r *http.Request) log.Printf("[WARN] [http,stacks,git] [error: %s] [message: failed restoring backup folder]", restoreError) } - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to clone git repository", Err: err} + return httperror.InternalServerError("Unable to clone git repository", err) } defer func() { @@ -174,13 +174,13 @@ func (handler *Handler) stackGitRedeploy(w http.ResponseWriter, r *http.Request) newHash, err := handler.GitService.LatestCommitID(stack.GitConfig.URL, stack.GitConfig.ReferenceName, repositoryUsername, repositoryPassword) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable get latest commit id", Err: errors.WithMessagef(err, "failed to fetch latest commit id of the stack %v", stack.ID)} + return httperror.InternalServerError("Unable get latest commit id", errors.WithMessagef(err, "failed to fetch latest commit id of the stack %v", stack.ID)) } stack.GitConfig.ConfigHash = newHash user, err := handler.DataStore.User().User(securityContext.UserID) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Cannot find context user", Err: errors.Wrap(err, "failed to fetch the user")} + return httperror.BadRequest("Cannot find context user", errors.Wrap(err, "failed to fetch the user")) } stack.UpdatedBy = user.Username stack.UpdateDate = time.Now().Unix() @@ -188,7 +188,7 @@ func (handler *Handler) stackGitRedeploy(w http.ResponseWriter, r *http.Request) 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: errors.Wrap(err, "failed to update the stack")} + return httperror.InternalServerError("Unable to persist the stack changes inside the database", errors.Wrap(err, "failed to update the stack")) } if stack.GitConfig != nil && stack.GitConfig.Authentication != nil && stack.GitConfig.Authentication.Password != "" { @@ -212,7 +212,7 @@ func (handler *Handler) deployStack(r *http.Request, stack *portainer.Stack, end } if err := handler.deploySwarmStack(config); err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: err.Error(), Err: err} + return httperror.InternalServerError(err.Error(), err) } case portainer.DockerComposeStack: @@ -222,13 +222,13 @@ func (handler *Handler) deployStack(r *http.Request, stack *portainer.Stack, end } if err := handler.deployComposeStack(config, true); err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: err.Error(), Err: err} + return httperror.InternalServerError(err.Error(), err) } case portainer.KubernetesStack: tokenData, err := security.RetrieveTokenData(r) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Failed to retrieve user token data", Err: err} + return httperror.BadRequest("Failed to retrieve user token data", err) } _, err = handler.deployKubernetesStack(tokenData.ID, endpoint, stack, k.KubeAppLabels{ StackID: int(stack.ID), @@ -237,11 +237,11 @@ func (handler *Handler) deployStack(r *http.Request, stack *portainer.Stack, end Kind: "git", }) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to redeploy Kubernetes stack", Err: errors.WithMessage(err, "failed to deploy kube application")} + return httperror.InternalServerError("Unable to redeploy Kubernetes stack", errors.WithMessage(err, "failed to deploy kube application")) } default: - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unsupported stack", Err: errors.Errorf("unsupported stack type: %v", stack.Type)} + return httperror.InternalServerError("Unsupported stack", errors.Errorf("unsupported stack type: %v", stack.Type)) } return nil diff --git a/api/http/handler/stacks/update_kubernetes_stack.go b/api/http/handler/stacks/update_kubernetes_stack.go index a534e61c8..28b0eb447 100644 --- a/api/http/handler/stacks/update_kubernetes_stack.go +++ b/api/http/handler/stacks/update_kubernetes_stack.go @@ -56,7 +56,7 @@ func (handler *Handler) updateKubernetesStack(r *http.Request, stack *portainer. var payload kubernetesGitStackUpdatePayload if err := request.DecodeAndValidateJSONPayload(r, &payload); err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } stack.GitConfig.ReferenceName = payload.RepositoryReferenceName @@ -73,7 +73,7 @@ func (handler *Handler) updateKubernetesStack(r *http.Request, stack *portainer. } _, err := handler.GitService.LatestCommitID(stack.GitConfig.URL, stack.GitConfig.ReferenceName, stack.GitConfig.Authentication.Username, stack.GitConfig.Authentication.Password) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to fetch git repository", Err: err} + return httperror.InternalServerError("Unable to fetch git repository", err) } } else { stack.GitConfig.Authentication = nil @@ -94,19 +94,19 @@ func (handler *Handler) updateKubernetesStack(r *http.Request, stack *portainer. err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid request payload", Err: err} + return httperror.BadRequest("Invalid request payload", err) } tokenData, err := security.RetrieveTokenData(r) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Failed to retrieve user token data", Err: err} + return httperror.BadRequest("Failed to retrieve user token data", err) } tempFileDir, _ := ioutil.TempDir("", "kub_file_content") defer os.RemoveAll(tempFileDir) if err := filesystem.WriteToFile(filesystem.JoinPaths(tempFileDir, stack.EntryPoint), []byte(payload.StackFileContent)); err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Failed to persist deployment file in a temp directory", Err: err} + return httperror.InternalServerError("Failed to persist deployment file in a temp directory", err) } //use temp dir as the stack project path for deployment @@ -121,7 +121,7 @@ func (handler *Handler) updateKubernetesStack(r *http.Request, stack *portainer. }) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to deploy Kubernetes stack via file content", Err: err} + return httperror.InternalServerError("Unable to deploy Kubernetes stack via file content", err) } stackFolder := strconv.Itoa(int(stack.ID)) @@ -136,7 +136,7 @@ func (handler *Handler) updateKubernetesStack(r *http.Request, stack *portainer. fileType = "Compose" } errMsg := fmt.Sprintf("Unable to persist Kubernetes %s file on disk", fileType) - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: errMsg, Err: err} + return httperror.InternalServerError(errMsg, err) } stack.ProjectPath = projectPath diff --git a/api/http/handler/stacks/webhook_invoke.go b/api/http/handler/stacks/webhook_invoke.go index a4768abd6..ef262e85f 100644 --- a/api/http/handler/stacks/webhook_invoke.go +++ b/api/http/handler/stacks/webhook_invoke.go @@ -27,7 +27,7 @@ import ( func (handler *Handler) webhookInvoke(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { webhookID, err := retrieveUUIDRouteVariableValue(r, "webhookID") if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusBadRequest, Message: "Invalid webhook identifier route variable", Err: err} + return httperror.BadRequest("Invalid webhook identifier route variable", err) } stack, err := handler.DataStore.Stack().StackByWebhookID(webhookID.String()) @@ -44,7 +44,7 @@ func (handler *Handler) webhookInvoke(w http.ResponseWriter, r *http.Request) *h return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Autoupdate for the stack isn't available", Err: err} } logrus.WithError(err).Error("failed to update the stack") - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Failed to update the stack", Err: err} + return httperror.InternalServerError("Failed to update the stack", err) } return response.Empty(w) diff --git a/api/http/handler/tags/tag_create.go b/api/http/handler/tags/tag_create.go index 12e0950ad..06ee233e6 100644 --- a/api/http/handler/tags/tag_create.go +++ b/api/http/handler/tags/tag_create.go @@ -41,17 +41,17 @@ func (handler *Handler) tagCreate(w http.ResponseWriter, r *http.Request) *httpe var payload tagCreatePayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } tags, err := handler.DataStore.Tag().Tags() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve tags from the database", err} + return httperror.InternalServerError("Unable to retrieve tags from the database", err) } for _, tag := range tags { if tag.Name == payload.Name { - return &httperror.HandlerError{http.StatusConflict, "This name is already associated to a tag", errors.New("A tag already exists with this name")} + return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "This name is already associated to a tag", Err: errors.New("A tag already exists with this name")} } } @@ -63,7 +63,7 @@ func (handler *Handler) tagCreate(w http.ResponseWriter, r *http.Request) *httpe err = handler.DataStore.Tag().Create(tag) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist the tag inside the database", err} + return httperror.InternalServerError("Unable to persist the tag inside the database", err) } return response.JSON(w, tag) diff --git a/api/http/handler/tags/tag_delete.go b/api/http/handler/tags/tag_delete.go index c252d4c1c..b87a7f3d3 100644 --- a/api/http/handler/tags/tag_delete.go +++ b/api/http/handler/tags/tag_delete.go @@ -27,21 +27,21 @@ import ( func (handler *Handler) tagDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { id, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid tag identifier route variable", err} + return httperror.BadRequest("Invalid tag identifier route variable", err) } tagID := portainer.TagID(id) tag, err := handler.DataStore.Tag().Tag(tagID) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a tag with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a tag with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a tag with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a tag with the specified identifier inside the database", err) } for endpointID := range tag.Endpoints { endpoint, err := handler.DataStore.Endpoint().Endpoint(endpointID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve environment from the database", err} + return httperror.InternalServerError("Unable to retrieve environment from the database", err) } tagIdx := findTagIndex(endpoint.TagIDs, tagID) @@ -49,7 +49,7 @@ func (handler *Handler) tagDelete(w http.ResponseWriter, r *http.Request) *httpe endpoint.TagIDs = removeElement(endpoint.TagIDs, tagIdx) err = handler.DataStore.Endpoint().UpdateEndpoint(endpoint.ID, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to update environment", err} + return httperror.InternalServerError("Unable to update environment", err) } } } @@ -57,7 +57,7 @@ func (handler *Handler) tagDelete(w http.ResponseWriter, r *http.Request) *httpe for endpointGroupID := range tag.EndpointGroups { endpointGroup, err := handler.DataStore.EndpointGroup().EndpointGroup(endpointGroupID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve environment group from the database", err} + return httperror.InternalServerError("Unable to retrieve environment group from the database", err) } tagIdx := findTagIndex(endpointGroup.TagIDs, tagID) @@ -65,31 +65,31 @@ func (handler *Handler) tagDelete(w http.ResponseWriter, r *http.Request) *httpe endpointGroup.TagIDs = removeElement(endpointGroup.TagIDs, tagIdx) err = handler.DataStore.EndpointGroup().UpdateEndpointGroup(endpointGroup.ID, endpointGroup) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to update environment group", err} + return httperror.InternalServerError("Unable to update environment group", err) } } } endpoints, err := handler.DataStore.Endpoint().Endpoints() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve environments from the database", err} + return httperror.InternalServerError("Unable to retrieve environments from the database", err) } edgeGroups, err := handler.DataStore.EdgeGroup().EdgeGroups() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve edge groups from the database", err} + return httperror.InternalServerError("Unable to retrieve edge groups from the database", err) } edgeStacks, err := handler.DataStore.EdgeStack().EdgeStacks() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve edge stacks from the database", err} + return httperror.InternalServerError("Unable to retrieve edge stacks from the database", err) } for _, endpoint := range endpoints { if (tag.Endpoints[endpoint.ID] || tag.EndpointGroups[endpoint.GroupID]) && (endpoint.Type == portainer.EdgeAgentOnDockerEnvironment || endpoint.Type == portainer.EdgeAgentOnKubernetesEnvironment) { err = handler.updateEndpointRelations(endpoint, edgeGroups, edgeStacks) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to update environment relations in the database", err} + return httperror.InternalServerError("Unable to update environment relations in the database", err) } } } @@ -101,14 +101,14 @@ func (handler *Handler) tagDelete(w http.ResponseWriter, r *http.Request) *httpe edgeGroup.TagIDs = removeElement(edgeGroup.TagIDs, tagIdx) err = handler.DataStore.EdgeGroup().UpdateEdgeGroup(edgeGroup.ID, edgeGroup) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to update environment group", err} + return httperror.InternalServerError("Unable to update environment group", err) } } } err = handler.DataStore.Tag().DeleteTag(tagID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove the tag from the database", err} + return httperror.InternalServerError("Unable to remove the tag from the database", err) } return response.Empty(w) diff --git a/api/http/handler/tags/tag_list.go b/api/http/handler/tags/tag_list.go index 9b7d427f4..c2c24a737 100644 --- a/api/http/handler/tags/tag_list.go +++ b/api/http/handler/tags/tag_list.go @@ -21,7 +21,7 @@ import ( func (handler *Handler) tagList(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { tags, err := handler.DataStore.Tag().Tags() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve tags from the database", err} + return httperror.InternalServerError("Unable to retrieve tags from the database", err) } return response.JSON(w, tags) diff --git a/api/http/handler/teammemberships/teammembership_create.go b/api/http/handler/teammemberships/teammembership_create.go index f550a0ab2..099ae92a3 100644 --- a/api/http/handler/teammemberships/teammembership_create.go +++ b/api/http/handler/teammemberships/teammembership_create.go @@ -55,27 +55,27 @@ func (handler *Handler) teamMembershipCreate(w http.ResponseWriter, r *http.Requ var payload teamMembershipCreatePayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } if !security.AuthorizedTeamManagement(portainer.TeamID(payload.TeamID), securityContext) { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to manage team memberships", httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Permission denied to manage team memberships", httperrors.ErrResourceAccessDenied) } memberships, err := handler.DataStore.TeamMembership().TeamMembershipsByUserID(portainer.UserID(payload.UserID)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve team memberships from the database", err} + return httperror.InternalServerError("Unable to retrieve team memberships from the database", err) } if len(memberships) > 0 { for _, membership := range memberships { if membership.UserID == portainer.UserID(payload.UserID) && membership.TeamID == portainer.TeamID(payload.TeamID) { - return &httperror.HandlerError{http.StatusConflict, "Team membership already registered", errors.New("Team membership already exists for this user and team")} + return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Team membership already registered", Err: errors.New("Team membership already exists for this user and team")} } } } @@ -88,7 +88,7 @@ func (handler *Handler) teamMembershipCreate(w http.ResponseWriter, r *http.Requ err = handler.DataStore.TeamMembership().Create(membership) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist team memberships inside the database", err} + return httperror.InternalServerError("Unable to persist team memberships inside the database", err) } return response.JSON(w, membership) diff --git a/api/http/handler/teammemberships/teammembership_delete.go b/api/http/handler/teammemberships/teammembership_delete.go index bc661dbd0..a398c983e 100644 --- a/api/http/handler/teammemberships/teammembership_delete.go +++ b/api/http/handler/teammemberships/teammembership_delete.go @@ -28,28 +28,28 @@ import ( func (handler *Handler) teamMembershipDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { membershipID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid membership identifier route variable", err} + return httperror.BadRequest("Invalid membership identifier route variable", err) } membership, err := handler.DataStore.TeamMembership().TeamMembership(portainer.TeamMembershipID(membershipID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a team membership with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a team membership with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a team membership with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a team membership with the specified identifier inside the database", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } if !security.AuthorizedTeamManagement(membership.TeamID, securityContext) { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to delete the membership", errors.ErrResourceAccessDenied} + return httperror.Forbidden("Permission denied to delete the membership", errors.ErrResourceAccessDenied) } err = handler.DataStore.TeamMembership().DeleteTeamMembership(portainer.TeamMembershipID(membershipID)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove the team membership from the database", err} + return httperror.InternalServerError("Unable to remove the team membership from the database", err) } return response.Empty(w) diff --git a/api/http/handler/teammemberships/teammembership_list.go b/api/http/handler/teammemberships/teammembership_list.go index afaa58d41..7ed32a354 100644 --- a/api/http/handler/teammemberships/teammembership_list.go +++ b/api/http/handler/teammemberships/teammembership_list.go @@ -23,7 +23,7 @@ import ( func (handler *Handler) teamMembershipList(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { memberships, err := handler.DataStore.TeamMembership().TeamMemberships() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve team memberships from the database", err} + return httperror.InternalServerError("Unable to retrieve team memberships from the database", err) } return response.JSON(w, memberships) diff --git a/api/http/handler/teammemberships/teammembership_update.go b/api/http/handler/teammemberships/teammembership_update.go index a54eb5205..09d77d642 100644 --- a/api/http/handler/teammemberships/teammembership_update.go +++ b/api/http/handler/teammemberships/teammembership_update.go @@ -54,31 +54,31 @@ func (payload *teamMembershipUpdatePayload) Validate(r *http.Request) error { func (handler *Handler) teamMembershipUpdate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { membershipID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid membership identifier route variable", err} + return httperror.BadRequest("Invalid membership identifier route variable", err) } var payload teamMembershipUpdatePayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } membership, err := handler.DataStore.TeamMembership().TeamMembership(portainer.TeamMembershipID(membershipID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a team membership with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a team membership with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a team membership with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a team membership with the specified identifier inside the database", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } isLeadingBothTeam := security.AuthorizedTeamManagement(portainer.TeamID(payload.TeamID), securityContext) && security.AuthorizedTeamManagement(membership.TeamID, securityContext) if !(securityContext.IsAdmin || isLeadingBothTeam) { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to update the membership", httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Permission denied to update the membership", httperrors.ErrResourceAccessDenied) } membership.UserID = portainer.UserID(payload.UserID) @@ -87,7 +87,7 @@ func (handler *Handler) teamMembershipUpdate(w http.ResponseWriter, r *http.Requ err = handler.DataStore.TeamMembership().UpdateTeamMembership(membership.ID, membership) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist membership changes inside the database", err} + return httperror.InternalServerError("Unable to persist membership changes inside the database", err) } return response.JSON(w, membership) diff --git a/api/http/handler/teams/team_create.go b/api/http/handler/teams/team_create.go index 6f6035e24..18cdef628 100644 --- a/api/http/handler/teams/team_create.go +++ b/api/http/handler/teams/team_create.go @@ -44,15 +44,15 @@ func (handler *Handler) teamCreate(w http.ResponseWriter, r *http.Request) *http var payload teamCreatePayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } team, err := handler.DataStore.Team().TeamByName(payload.Name) if err != nil && !handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve teams from the database", err} + return httperror.InternalServerError("Unable to retrieve teams from the database", err) } if team != nil { - return &httperror.HandlerError{http.StatusConflict, "A team with the same name already exists", errors.New("Team already exists")} + return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "A team with the same name already exists", Err: errors.New("Team already exists")} } team = &portainer.Team{ @@ -61,7 +61,7 @@ func (handler *Handler) teamCreate(w http.ResponseWriter, r *http.Request) *http err = handler.DataStore.Team().Create(team) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist the team inside the database", err} + return httperror.InternalServerError("Unable to persist the team inside the database", err) } for _, teamLeader := range payload.TeamLeaders { @@ -73,7 +73,7 @@ func (handler *Handler) teamCreate(w http.ResponseWriter, r *http.Request) *http err = handler.DataStore.TeamMembership().Create(membership) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist team leadership inside the database", err} + return httperror.InternalServerError("Unable to persist team leadership inside the database", err) } } diff --git a/api/http/handler/teams/team_delete.go b/api/http/handler/teams/team_delete.go index cea1585dc..e67f427c2 100644 --- a/api/http/handler/teams/team_delete.go +++ b/api/http/handler/teams/team_delete.go @@ -27,30 +27,30 @@ import ( func (handler *Handler) teamDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { teamID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid team identifier route variable", err} + return httperror.BadRequest("Invalid team identifier route variable", err) } _, err = handler.DataStore.Team().Team(portainer.TeamID(teamID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a team with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a team with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a team with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a team with the specified identifier inside the database", err) } err = handler.DataStore.Team().DeleteTeam(portainer.TeamID(teamID)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to delete the team from the database", err} + return httperror.InternalServerError("Unable to delete the team from the database", err) } err = handler.DataStore.TeamMembership().DeleteTeamMembershipByTeamID(portainer.TeamID(teamID)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to delete associated team memberships from the database", err} + return httperror.InternalServerError("Unable to delete associated team memberships from the database", err) } // update default team if deleted team was default err = handler.updateDefaultTeamIfDeleted(portainer.TeamID(teamID)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to reset default team", err} + return httperror.InternalServerError("Unable to reset default team", err) } return response.Empty(w) diff --git a/api/http/handler/teams/team_inspect.go b/api/http/handler/teams/team_inspect.go index 8e1c90bc5..d94bbc9fd 100644 --- a/api/http/handler/teams/team_inspect.go +++ b/api/http/handler/teams/team_inspect.go @@ -30,23 +30,23 @@ import ( func (handler *Handler) teamInspect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { teamID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid team identifier route variable", err} + return httperror.BadRequest("Invalid team identifier route variable", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } if !security.AuthorizedTeamManagement(portainer.TeamID(teamID), securityContext) { - return &httperror.HandlerError{http.StatusForbidden, "Access denied to team", errors.ErrResourceAccessDenied} + return httperror.Forbidden("Access denied to team", errors.ErrResourceAccessDenied) } team, err := handler.DataStore.Team().Team(portainer.TeamID(teamID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a team with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a team with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a team with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a team with the specified identifier inside the database", err) } return response.JSON(w, team) diff --git a/api/http/handler/teams/team_memberships.go b/api/http/handler/teams/team_memberships.go index 7be4090e5..ada0bc150 100644 --- a/api/http/handler/teams/team_memberships.go +++ b/api/http/handler/teams/team_memberships.go @@ -28,21 +28,21 @@ import ( func (handler *Handler) teamMemberships(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { teamID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid team identifier route variable", err} + return httperror.BadRequest("Invalid team identifier route variable", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } if !security.AuthorizedTeamManagement(portainer.TeamID(teamID), securityContext) { - return &httperror.HandlerError{http.StatusForbidden, "Access denied to team", errors.ErrResourceAccessDenied} + return httperror.Forbidden("Access denied to team", errors.ErrResourceAccessDenied) } memberships, err := handler.DataStore.TeamMembership().TeamMembershipsByTeamID(portainer.TeamID(teamID)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve associated team memberships from the database", err} + return httperror.InternalServerError("Unable to retrieve associated team memberships from the database", err) } return response.JSON(w, memberships) diff --git a/api/http/handler/teams/team_update.go b/api/http/handler/teams/team_update.go index 50568ad71..f274bfddb 100644 --- a/api/http/handler/teams/team_update.go +++ b/api/http/handler/teams/team_update.go @@ -39,20 +39,20 @@ func (payload *teamUpdatePayload) Validate(r *http.Request) error { func (handler *Handler) teamUpdate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { teamID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid team identifier route variable", err} + return httperror.BadRequest("Invalid team identifier route variable", err) } var payload teamUpdatePayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } team, err := handler.DataStore.Team().Team(portainer.TeamID(teamID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a team with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a team with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a team with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a team with the specified identifier inside the database", err) } if payload.Name != "" { @@ -61,7 +61,7 @@ func (handler *Handler) teamUpdate(w http.ResponseWriter, r *http.Request) *http err = handler.DataStore.Team().UpdateTeam(team.ID, team) if err != nil { - return &httperror.HandlerError{http.StatusNotFound, "Unable to persist team changes inside the database", err} + return httperror.NotFound("Unable to persist team changes inside the database", err) } return response.JSON(w, team) diff --git a/api/http/handler/templates/template_file.go b/api/http/handler/templates/template_file.go index 8c046ce5a..1f4585dbe 100644 --- a/api/http/handler/templates/template_file.go +++ b/api/http/handler/templates/template_file.go @@ -40,12 +40,12 @@ func (payload *filePayload) Validate(r *http.Request) error { func (handler *Handler) ifRequestedTemplateExists(payload *filePayload) *httperror.HandlerError { settings, err := handler.DataStore.Settings().Settings() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve settings from the database", err} + return httperror.InternalServerError("Unable to retrieve settings from the database", err) } resp, err := http.Get(settings.TemplatesURL) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve templates via the network", err} + return httperror.InternalServerError("Unable to retrieve templates via the network", err) } defer resp.Body.Close() @@ -54,7 +54,7 @@ func (handler *Handler) ifRequestedTemplateExists(payload *filePayload) *httperr } err = json.NewDecoder(resp.Body).Decode(&templates) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to parse template file", err} + return httperror.InternalServerError("Unable to parse template file", err) } for _, t := range templates.Templates { @@ -62,7 +62,7 @@ func (handler *Handler) ifRequestedTemplateExists(payload *filePayload) *httperr return nil } } - return &httperror.HandlerError{http.StatusInternalServerError, "Invalid template", errors.New("requested template does not exist")} + return httperror.InternalServerError("Invalid template", errors.New("requested template does not exist")) } // @id TemplateFile @@ -83,7 +83,7 @@ func (handler *Handler) templateFile(w http.ResponseWriter, r *http.Request) *ht var payload filePayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } if err := handler.ifRequestedTemplateExists(&payload); err != nil { @@ -92,19 +92,19 @@ func (handler *Handler) templateFile(w http.ResponseWriter, r *http.Request) *ht projectPath, err := handler.FileService.GetTemporaryPath() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to create temporary folder", err} + return httperror.InternalServerError("Unable to create temporary folder", err) } defer handler.cleanUp(projectPath) err = handler.GitService.CloneRepository(projectPath, payload.RepositoryURL, "", "", "") if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to clone git repository", err} + return httperror.InternalServerError("Unable to clone git repository", err) } fileContent, err := handler.FileService.GetFileContent(projectPath, payload.ComposeFilePathInRepository) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Failed loading file content", err} + return httperror.InternalServerError("Failed loading file content", err) } return response.JSON(w, fileResponse{FileContent: string(fileContent)}) diff --git a/api/http/handler/templates/template_list.go b/api/http/handler/templates/template_list.go index e784443de..14cfad20b 100644 --- a/api/http/handler/templates/template_list.go +++ b/api/http/handler/templates/template_list.go @@ -28,19 +28,19 @@ type listResponse struct { func (handler *Handler) templateList(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { settings, err := handler.DataStore.Settings().Settings() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve settings from the database", err} + return httperror.InternalServerError("Unable to retrieve settings from the database", err) } resp, err := http.Get(settings.TemplatesURL) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve templates via the network", err} + return httperror.InternalServerError("Unable to retrieve templates via the network", err) } defer resp.Body.Close() w.Header().Set("Content-Type", "application/json") _, err = io.Copy(w, resp.Body) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to write templates from templates URL", err} + return httperror.InternalServerError("Unable to write templates from templates URL", err) } return nil diff --git a/api/http/handler/upload/upload_tls.go b/api/http/handler/upload/upload_tls.go index db3ba7c5f..f1e46297b 100644 --- a/api/http/handler/upload/upload_tls.go +++ b/api/http/handler/upload/upload_tls.go @@ -29,17 +29,17 @@ import ( func (handler *Handler) uploadTLS(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { certificate, err := request.RetrieveRouteVariableValue(r, "certificate") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid certificate route variable", err} + return httperror.BadRequest("Invalid certificate route variable", err) } folder, err := request.RetrieveMultiPartFormValue(r, "folder", false) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: folder", err} + return httperror.BadRequest("Invalid query parameter: folder", err) } file, _, err := request.RetrieveMultiPartFormFile(r, "file") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid certificate file. Ensure that the certificate file is uploaded correctly", err} + return httperror.BadRequest("Invalid certificate file. Ensure that the certificate file is uploaded correctly", err) } var fileType portainer.TLSFileType @@ -51,12 +51,12 @@ func (handler *Handler) uploadTLS(w http.ResponseWriter, r *http.Request) *httpe case "key": fileType = portainer.TLSFileKey default: - return &httperror.HandlerError{http.StatusBadRequest, "Invalid certificate route value. Value must be one of: ca, cert or key", filesystem.ErrUndefinedTLSFileType} + return httperror.BadRequest("Invalid certificate route value. Value must be one of: ca, cert or key", filesystem.ErrUndefinedTLSFileType) } _, err = handler.FileService.StoreTLSFileFromBytes(folder, fileType, file) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist certificate file on disk", err} + return httperror.InternalServerError("Unable to persist certificate file on disk", err) } return response.Empty(w) diff --git a/api/http/handler/users/admin_check.go b/api/http/handler/users/admin_check.go index 59393c1e2..1925981ee 100644 --- a/api/http/handler/users/admin_check.go +++ b/api/http/handler/users/admin_check.go @@ -20,11 +20,11 @@ import ( func (handler *Handler) adminCheck(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { users, err := handler.DataStore.User().UsersByRole(portainer.AdministratorRole) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve users from the database", err} + return httperror.InternalServerError("Unable to retrieve users from the database", err) } if len(users) == 0 { - return &httperror.HandlerError{http.StatusNotFound, "No administrator account found inside the database", errors.ErrObjectNotFound} + return httperror.NotFound("No administrator account found inside the database", errors.ErrObjectNotFound) } return response.Empty(w) diff --git a/api/http/handler/users/admin_init.go b/api/http/handler/users/admin_init.go index 8a2154242..c40c16394 100644 --- a/api/http/handler/users/admin_init.go +++ b/api/http/handler/users/admin_init.go @@ -45,20 +45,20 @@ func (handler *Handler) adminInit(w http.ResponseWriter, r *http.Request) *httpe var payload adminInitPayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } users, err := handler.DataStore.User().UsersByRole(portainer.AdministratorRole) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve users from the database", err} + return httperror.InternalServerError("Unable to retrieve users from the database", err) } if len(users) != 0 { - return &httperror.HandlerError{http.StatusConflict, "Unable to create administrator user", errAdminAlreadyInitialized} + return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Unable to create administrator user", Err: errAdminAlreadyInitialized} } if !handler.passwordStrengthChecker.Check(payload.Password) { - return &httperror.HandlerError{http.StatusBadRequest, "Password does not meet the requirements", nil} + return httperror.BadRequest("Password does not meet the requirements", nil) } user := &portainer.User{ @@ -68,12 +68,12 @@ func (handler *Handler) adminInit(w http.ResponseWriter, r *http.Request) *httpe user.Password, err = handler.CryptoService.Hash(payload.Password) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to hash user password", errCryptoHashFailure} + return httperror.InternalServerError("Unable to hash user password", errCryptoHashFailure) } err = handler.DataStore.User().Create(user) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist user inside the database", err} + return httperror.InternalServerError("Unable to persist user inside the database", err) } return response.JSON(w, user) diff --git a/api/http/handler/users/user_create.go b/api/http/handler/users/user_create.go index e2b1e68cf..8d913a6cd 100644 --- a/api/http/handler/users/user_create.go +++ b/api/http/handler/users/user_create.go @@ -50,15 +50,15 @@ func (handler *Handler) userCreate(w http.ResponseWriter, r *http.Request) *http var payload userCreatePayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } user, err := handler.DataStore.User().UserByUsername(payload.Username) if err != nil && !handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve users from the database", err} + return httperror.InternalServerError("Unable to retrieve users from the database", err) } if user != nil { - return &httperror.HandlerError{http.StatusConflict, "Another user with the same username already exists", errUserAlreadyExists} + return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Another user with the same username already exists", Err: errUserAlreadyExists} } user = &portainer.User{ @@ -68,29 +68,29 @@ func (handler *Handler) userCreate(w http.ResponseWriter, r *http.Request) *http settings, err := handler.DataStore.Settings().Settings() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve settings from the database", err} + return httperror.InternalServerError("Unable to retrieve settings from the database", err) } // when ldap/oauth is on, can only add users without password if (settings.AuthenticationMethod == portainer.AuthenticationLDAP || settings.AuthenticationMethod == portainer.AuthenticationOAuth) && payload.Password != "" { errMsg := "A user with password can not be created when authentication method is Oauth or LDAP" - return &httperror.HandlerError{http.StatusBadRequest, errMsg, errors.New(errMsg)} + return httperror.BadRequest(errMsg, errors.New(errMsg)) } if settings.AuthenticationMethod == portainer.AuthenticationInternal { if !handler.passwordStrengthChecker.Check(payload.Password) { - return &httperror.HandlerError{http.StatusBadRequest, "Password does not meet the requirements", nil} + return httperror.BadRequest("Password does not meet the requirements", nil) } user.Password, err = handler.CryptoService.Hash(payload.Password) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to hash user password", errCryptoHashFailure} + return httperror.InternalServerError("Unable to hash user password", errCryptoHashFailure) } } err = handler.DataStore.User().Create(user) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist user inside the database", err} + return httperror.InternalServerError("Unable to persist user inside the database", err) } hideFields(user) diff --git a/api/http/handler/users/user_create_access_token.go b/api/http/handler/users/user_create_access_token.go index ad8fb880d..ea5a32836 100644 --- a/api/http/handler/users/user_create_access_token.go +++ b/api/http/handler/users/user_create_access_token.go @@ -56,37 +56,37 @@ type accessTokenResponse struct { func (handler *Handler) userCreateAccessToken(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { // specifically require JWT auth for this endpoint since API-Key based auth is not supported if jwt := handler.bouncer.JWTAuthLookup(r); jwt == nil { - return &httperror.HandlerError{http.StatusUnauthorized, "Auth not supported", errors.New("JWT Authentication required")} + return httperror.Unauthorized("Auth not supported", errors.New("JWT Authentication required")) } var payload userAccessTokenCreatePayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } userID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid user identifier route variable", err} + return httperror.BadRequest("Invalid user identifier route variable", err) } tokenData, err := security.RetrieveTokenData(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user authentication token", err} + return httperror.InternalServerError("Unable to retrieve user authentication token", err) } if tokenData.ID != portainer.UserID(userID) { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to create user access token", httperrors.ErrUnauthorized} + return httperror.Forbidden("Permission denied to create user access token", httperrors.ErrUnauthorized) } user, err := handler.DataStore.User().User(portainer.UserID(userID)) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Unable to find a user", err} + return httperror.BadRequest("Unable to find a user", err) } rawAPIKey, apiKey, err := handler.apiKeyService.GenerateApiKey(*user, payload.Description) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Internal Server Error", err} + return httperror.InternalServerError("Internal Server Error", err) } w.WriteHeader(http.StatusCreated) diff --git a/api/http/handler/users/user_delete.go b/api/http/handler/users/user_delete.go index db344a080..242747b5d 100644 --- a/api/http/handler/users/user_delete.go +++ b/api/http/handler/users/user_delete.go @@ -29,27 +29,27 @@ import ( func (handler *Handler) userDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { userID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid user identifier route variable", err} + return httperror.BadRequest("Invalid user identifier route variable", err) } if userID == 1 { - return &httperror.HandlerError{http.StatusForbidden, "Cannot remove the initial admin account", errors.New("Cannot remove the initial admin account")} + return httperror.Forbidden("Cannot remove the initial admin account", errors.New("Cannot remove the initial admin account")) } tokenData, err := security.RetrieveTokenData(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user authentication token", err} + return httperror.InternalServerError("Unable to retrieve user authentication token", err) } if tokenData.ID == portainer.UserID(userID) { - return &httperror.HandlerError{http.StatusForbidden, "Cannot remove your own user account. Contact another administrator", errAdminCannotRemoveSelf} + return httperror.Forbidden("Cannot remove your own user account. Contact another administrator", errAdminCannotRemoveSelf) } user, err := handler.DataStore.User().User(portainer.UserID(userID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a user with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a user with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a user with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a user with the specified identifier inside the database", err) } if user.Role == portainer.AdministratorRole { @@ -66,7 +66,7 @@ func (handler *Handler) deleteAdminUser(w http.ResponseWriter, user *portainer.U users, err := handler.DataStore.User().Users() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve users from the database", err} + return httperror.InternalServerError("Unable to retrieve users from the database", err) } localAdminCount := 0 @@ -77,7 +77,7 @@ func (handler *Handler) deleteAdminUser(w http.ResponseWriter, user *portainer.U } if localAdminCount < 2 { - return &httperror.HandlerError{http.StatusInternalServerError, "Cannot remove local administrator user", errCannotRemoveLastLocalAdmin} + return httperror.InternalServerError("Cannot remove local administrator user", errCannotRemoveLastLocalAdmin) } return handler.deleteUser(w, user) @@ -86,23 +86,23 @@ func (handler *Handler) deleteAdminUser(w http.ResponseWriter, user *portainer.U func (handler *Handler) deleteUser(w http.ResponseWriter, user *portainer.User) *httperror.HandlerError { err := handler.DataStore.User().DeleteUser(user.ID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove user from the database", err} + return httperror.InternalServerError("Unable to remove user from the database", err) } err = handler.DataStore.TeamMembership().DeleteTeamMembershipByUserID(user.ID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove user memberships from the database", err} + return httperror.InternalServerError("Unable to remove user memberships from the database", err) } // Remove all of the users persisted API keys apiKeys, err := handler.apiKeyService.GetAPIKeys(user.ID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user API keys from the database", err} + return httperror.InternalServerError("Unable to retrieve user API keys from the database", err) } for _, k := range apiKeys { err = handler.apiKeyService.DeleteAPIKey(k.ID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove user API key from the database", err} + return httperror.InternalServerError("Unable to remove user API key from the database", err) } } diff --git a/api/http/handler/users/user_get_access_tokens.go b/api/http/handler/users/user_get_access_tokens.go index ac04adccd..47e2b69ef 100644 --- a/api/http/handler/users/user_get_access_tokens.go +++ b/api/http/handler/users/user_get_access_tokens.go @@ -30,29 +30,29 @@ import ( func (handler *Handler) userGetAccessTokens(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { userID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid user identifier route variable", err} + return httperror.BadRequest("Invalid user identifier route variable", err) } tokenData, err := security.RetrieveTokenData(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user authentication token", err} + return httperror.InternalServerError("Unable to retrieve user authentication token", err) } if tokenData.Role != portainer.AdministratorRole && tokenData.ID != portainer.UserID(userID) { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to get user access tokens", httperrors.ErrUnauthorized} + return httperror.Forbidden("Permission denied to get user access tokens", httperrors.ErrUnauthorized) } _, err = handler.DataStore.User().User(portainer.UserID(userID)) if err != nil { if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a user with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a user with the specified identifier inside the database", err) } - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a user with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a user with the specified identifier inside the database", err) } apiKeys, err := handler.apiKeyService.GetAPIKeys(portainer.UserID(userID)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Internal Server Error", err} + return httperror.InternalServerError("Internal Server Error", err) } for idx := range apiKeys { diff --git a/api/http/handler/users/user_inspect.go b/api/http/handler/users/user_inspect.go index 7ab848f3f..160fde89f 100644 --- a/api/http/handler/users/user_inspect.go +++ b/api/http/handler/users/user_inspect.go @@ -30,23 +30,23 @@ import ( func (handler *Handler) userInspect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { userID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid user identifier route variable", err} + return httperror.BadRequest("Invalid user identifier route variable", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } if !securityContext.IsAdmin && securityContext.UserID != portainer.UserID(userID) { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied inspect user", errors.ErrResourceAccessDenied} + return httperror.Forbidden("Permission denied inspect user", errors.ErrResourceAccessDenied) } user, err := handler.DataStore.User().User(portainer.UserID(userID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a user with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a user with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a user with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a user with the specified identifier inside the database", err) } hideFields(user) diff --git a/api/http/handler/users/user_list.go b/api/http/handler/users/user_list.go index 869218342..610b17ae2 100644 --- a/api/http/handler/users/user_list.go +++ b/api/http/handler/users/user_list.go @@ -25,12 +25,12 @@ import ( func (handler *Handler) userList(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { users, err := handler.DataStore.User().Users() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve users from the database", err} + return httperror.InternalServerError("Unable to retrieve users from the database", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err} + return httperror.InternalServerError("Unable to retrieve info from request context", err) } filteredUsers := security.FilterUsers(users, securityContext) diff --git a/api/http/handler/users/user_memberships.go b/api/http/handler/users/user_memberships.go index 82a1b366e..9f52d87aa 100644 --- a/api/http/handler/users/user_memberships.go +++ b/api/http/handler/users/user_memberships.go @@ -28,21 +28,21 @@ import ( func (handler *Handler) userMemberships(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { userID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid user identifier route variable", err} + return httperror.BadRequest("Invalid user identifier route variable", err) } tokenData, err := security.RetrieveTokenData(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user authentication token", err} + return httperror.InternalServerError("Unable to retrieve user authentication token", err) } if tokenData.Role != portainer.AdministratorRole && tokenData.ID != portainer.UserID(userID) { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to update user memberships", errors.ErrUnauthorized} + return httperror.Forbidden("Permission denied to update user memberships", errors.ErrUnauthorized) } memberships, err := handler.DataStore.TeamMembership().TeamMembershipsByUserID(portainer.UserID(userID)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist membership changes inside the database", err} + return httperror.InternalServerError("Unable to persist membership changes inside the database", err) } return response.JSON(w, memberships) diff --git a/api/http/handler/users/user_remove_access_token.go b/api/http/handler/users/user_remove_access_token.go index 21edde55e..be13ccad5 100644 --- a/api/http/handler/users/user_remove_access_token.go +++ b/api/http/handler/users/user_remove_access_token.go @@ -31,45 +31,45 @@ import ( func (handler *Handler) userRemoveAccessToken(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { userID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid user identifier route variable", err} + return httperror.BadRequest("Invalid user identifier route variable", err) } apiKeyID, err := request.RetrieveNumericRouteVariableValue(r, "keyID") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid api-key identifier route variable", err} + return httperror.BadRequest("Invalid api-key identifier route variable", err) } tokenData, err := security.RetrieveTokenData(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user authentication token", err} + return httperror.InternalServerError("Unable to retrieve user authentication token", err) } if tokenData.Role != portainer.AdministratorRole && tokenData.ID != portainer.UserID(userID) { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to get user access tokens", httperrors.ErrUnauthorized} + return httperror.Forbidden("Permission denied to get user access tokens", httperrors.ErrUnauthorized) } _, err = handler.DataStore.User().User(portainer.UserID(userID)) if err != nil { if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a user with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a user with the specified identifier inside the database", err) } - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a user with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a user with the specified identifier inside the database", err) } // check if the key exists and the key belongs to the user apiKey, err := handler.apiKeyService.GetAPIKey(portainer.APIKeyID(apiKeyID)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "API Key not found", err} + return httperror.InternalServerError("API Key not found", err) } if apiKey.UserID != portainer.UserID(userID) { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to remove api-key", httperrors.ErrUnauthorized} + return httperror.Forbidden("Permission denied to remove api-key", httperrors.ErrUnauthorized) } err = handler.apiKeyService.DeleteAPIKey(portainer.APIKeyID(apiKeyID)) if err != nil { if err == apikey.ErrInvalidAPIKey { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an api-key with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an api-key with the specified identifier inside the database", err) } - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove the api-key from the user", err} + return httperror.InternalServerError("Unable to remove the api-key from the user", err) } return response.Empty(w) diff --git a/api/http/handler/users/user_update.go b/api/http/handler/users/user_update.go index 064aa1c68..60d650855 100644 --- a/api/http/handler/users/user_update.go +++ b/api/http/handler/users/user_update.go @@ -54,46 +54,46 @@ func (payload *userUpdatePayload) Validate(r *http.Request) error { func (handler *Handler) userUpdate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { userID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid user identifier route variable", err} + return httperror.BadRequest("Invalid user identifier route variable", err) } if handler.demoService.IsDemoUser(portainer.UserID(userID)) { - return &httperror.HandlerError{http.StatusForbidden, httperrors.ErrNotAvailableInDemo.Error(), httperrors.ErrNotAvailableInDemo} + return httperror.Forbidden(httperrors.ErrNotAvailableInDemo.Error(), httperrors.ErrNotAvailableInDemo) } tokenData, err := security.RetrieveTokenData(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user authentication token", err} + return httperror.InternalServerError("Unable to retrieve user authentication token", err) } if tokenData.Role != portainer.AdministratorRole && tokenData.ID != portainer.UserID(userID) { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to update user", httperrors.ErrUnauthorized} + return httperror.Forbidden("Permission denied to update user", httperrors.ErrUnauthorized) } var payload userUpdatePayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } if tokenData.Role != portainer.AdministratorRole && payload.Role != 0 { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to update user to administrator role", httperrors.ErrResourceAccessDenied} + return httperror.Forbidden("Permission denied to update user to administrator role", httperrors.ErrResourceAccessDenied) } user, err := handler.DataStore.User().User(portainer.UserID(userID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a user with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a user with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a user with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a user with the specified identifier inside the database", err) } if payload.Username != "" && payload.Username != user.Username { sameNameUser, err := handler.DataStore.User().UserByUsername(payload.Username) if err != nil && !handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve users from the database", err} + return httperror.InternalServerError("Unable to retrieve users from the database", err) } if sameNameUser != nil && sameNameUser.ID != portainer.UserID(userID) { - return &httperror.HandlerError{http.StatusConflict, "Another user with the same username already exists", errUserAlreadyExists} + return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Another user with the same username already exists", Err: errUserAlreadyExists} } user.Username = payload.Username @@ -102,7 +102,7 @@ func (handler *Handler) userUpdate(w http.ResponseWriter, r *http.Request) *http if payload.Password != "" { user.Password, err = handler.CryptoService.Hash(payload.Password) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to hash user password", errCryptoHashFailure} + return httperror.InternalServerError("Unable to hash user password", errCryptoHashFailure) } user.TokenIssueAt = time.Now().Unix() } @@ -117,7 +117,7 @@ func (handler *Handler) userUpdate(w http.ResponseWriter, r *http.Request) *http err = handler.DataStore.User().UpdateUser(user.ID, user) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist user changes inside the database", err} + return httperror.InternalServerError("Unable to persist user changes inside the database", err) } // remove all of the users persisted API keys diff --git a/api/http/handler/users/user_update_password.go b/api/http/handler/users/user_update_password.go index e0fa98298..bfca121fb 100644 --- a/api/http/handler/users/user_update_password.go +++ b/api/http/handler/users/user_update_password.go @@ -51,54 +51,54 @@ func (payload *userUpdatePasswordPayload) Validate(r *http.Request) error { func (handler *Handler) userUpdatePassword(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { userID, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid user identifier route variable", err} + return httperror.BadRequest("Invalid user identifier route variable", err) } if handler.demoService.IsDemoUser(portainer.UserID(userID)) { - return &httperror.HandlerError{http.StatusForbidden, httperrors.ErrNotAvailableInDemo.Error(), httperrors.ErrNotAvailableInDemo} + return httperror.Forbidden(httperrors.ErrNotAvailableInDemo.Error(), httperrors.ErrNotAvailableInDemo) } tokenData, err := security.RetrieveTokenData(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user authentication token", err} + return httperror.InternalServerError("Unable to retrieve user authentication token", err) } if tokenData.Role != portainer.AdministratorRole && tokenData.ID != portainer.UserID(userID) { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to update user", httperrors.ErrUnauthorized} + return httperror.Forbidden("Permission denied to update user", httperrors.ErrUnauthorized) } var payload userUpdatePasswordPayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } user, err := handler.DataStore.User().User(portainer.UserID(userID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a user with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a user with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a user with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a user with the specified identifier inside the database", err) } err = handler.CryptoService.CompareHashAndData(user.Password, payload.Password) if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Current password doesn't match", errors.New("Current password does not match the password provided. Please try again")} + return httperror.Forbidden("Current password doesn't match", errors.New("Current password does not match the password provided. Please try again")) } if !handler.passwordStrengthChecker.Check(payload.NewPassword) { - return &httperror.HandlerError{http.StatusBadRequest, "Password does not meet the requirements", nil} + return httperror.BadRequest("Password does not meet the requirements", nil) } user.Password, err = handler.CryptoService.Hash(payload.NewPassword) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to hash user password", errCryptoHashFailure} + return httperror.InternalServerError("Unable to hash user password", errCryptoHashFailure) } user.TokenIssueAt = time.Now().Unix() err = handler.DataStore.User().UpdateUser(user.ID, user) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist user changes inside the database", err} + return httperror.InternalServerError("Unable to persist user changes inside the database", err) } return response.Empty(w) diff --git a/api/http/handler/webhooks/handler.go b/api/http/handler/webhooks/handler.go index 665b70365..dcf86a82d 100644 --- a/api/http/handler/webhooks/handler.go +++ b/api/http/handler/webhooks/handler.go @@ -42,12 +42,12 @@ func NewHandler(bouncer *security.RequestBouncer) *Handler { func (handler *Handler) checkResourceAccess(r *http.Request, resourceID string, resourceControlType portainer.ResourceControlType) *httperror.HandlerError { securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve user info from request context", Err: err} + return httperror.InternalServerError("Unable to retrieve user info from request context", err) } // non-admins rc, err := handler.DataStore.ResourceControl().ResourceControlByResourceIDAndType(resourceID, resourceControlType) if rc == nil || err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve a resource control associated to the resource", Err: err} + return httperror.InternalServerError("Unable to retrieve a resource control associated to the resource", err) } userTeamIDs := make([]portainer.TeamID, 0) for _, membership := range securityContext.UserMemberships { @@ -63,18 +63,18 @@ func (handler *Handler) checkResourceAccess(r *http.Request, resourceID string, func (handler *Handler) checkAuthorization(r *http.Request, endpoint *portainer.Endpoint, authorizations []portainer.Authorization) (bool, *httperror.HandlerError) { err := handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) if err != nil { - return false, &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "Permission denied to access environment", Err: err} + return false, httperror.Forbidden("Permission denied to access environment", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return false, &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve user info from request context", Err: err} + return false, httperror.InternalServerError("Unable to retrieve user info from request context", err) } authService := authorization.NewService(handler.DataStore) isAdminOrAuthorized, err := authService.UserIsAdminOrAuthorized(securityContext.UserID, endpoint.ID, authorizations) if err != nil { - return false, &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to get user authorizations", Err: err} + return false, httperror.InternalServerError("Unable to get user authorizations", err) } return isAdminOrAuthorized, nil } diff --git a/api/http/handler/webhooks/webhook_create.go b/api/http/handler/webhooks/webhook_create.go index b0d7b00dc..3fe172525 100644 --- a/api/http/handler/webhooks/webhook_create.go +++ b/api/http/handler/webhooks/webhook_create.go @@ -2,9 +2,10 @@ package webhooks import ( "errors" + "net/http" + "github.com/portainer/portainer/api/http/security" "github.com/portainer/portainer/api/internal/registryutils/access" - "net/http" "github.com/asaskevich/govalidator" "github.com/gofrs/uuid" @@ -51,43 +52,43 @@ func (handler *Handler) webhookCreate(w http.ResponseWriter, r *http.Request) *h var payload webhookCreatePayload err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } webhook, err := handler.DataStore.Webhook().WebhookByResourceID(payload.ResourceID) if err != nil && !handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusInternalServerError, "An error occurred retrieving webhooks from the database", err} + return httperror.InternalServerError("An error occurred retrieving webhooks from the database", err) } if webhook != nil { - return &httperror.HandlerError{http.StatusConflict, "A webhook for this resource already exists", errors.New("A webhook for this resource already exists")} + return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "A webhook for this resource already exists", Err: errors.New("A webhook for this resource already exists")} } endpointID := portainer.EndpointID(payload.EndpointID) securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve user info from request context", Err: err} + return httperror.InternalServerError("Unable to retrieve user info from request context", err) } if !securityContext.IsAdmin { - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "Not authorized to create a webhook", Err: errors.New("not authorized to create a webhook")} + return httperror.Forbidden("Not authorized to create a webhook", errors.New("not authorized to create a webhook")) } if payload.RegistryID != 0 { tokenData, err := security.RetrieveTokenData(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user authentication token", err} + return httperror.InternalServerError("Unable to retrieve user authentication token", err) } _, err = access.GetAccessibleRegistry(handler.DataStore, tokenData.ID, endpointID, payload.RegistryID) if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission deny to access registry", err} + return httperror.Forbidden("Permission deny to access registry", err) } } token, err := uuid.NewV4() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Error creating unique token", err} + return httperror.InternalServerError("Error creating unique token", err) } webhook = &portainer.Webhook{ @@ -100,7 +101,7 @@ func (handler *Handler) webhookCreate(w http.ResponseWriter, r *http.Request) *h err = handler.DataStore.Webhook().Create(webhook) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist the webhook inside the database", err} + return httperror.InternalServerError("Unable to persist the webhook inside the database", err) } return response.JSON(w, webhook) diff --git a/api/http/handler/webhooks/webhook_delete.go b/api/http/handler/webhooks/webhook_delete.go index 422316c15..0b7f64747 100644 --- a/api/http/handler/webhooks/webhook_delete.go +++ b/api/http/handler/webhooks/webhook_delete.go @@ -24,21 +24,21 @@ import ( func (handler *Handler) webhookDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { id, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid webhook id", err} + return httperror.BadRequest("Invalid webhook id", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve user info from request context", Err: err} + return httperror.InternalServerError("Unable to retrieve user info from request context", err) } if !securityContext.IsAdmin { - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "Not authorized to delete a webhook", Err: errors.New("not authorized to delete a webhook")} + return httperror.Forbidden("Not authorized to delete a webhook", errors.New("not authorized to delete a webhook")) } err = handler.DataStore.Webhook().DeleteWebhook(portainer.WebhookID(id)) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove the webhook from the database", err} + return httperror.InternalServerError("Unable to remove the webhook from the database", err) } return response.Empty(w) diff --git a/api/http/handler/webhooks/webhook_execute.go b/api/http/handler/webhooks/webhook_execute.go index 9b0d581d7..0168e231d 100644 --- a/api/http/handler/webhooks/webhook_execute.go +++ b/api/http/handler/webhooks/webhook_execute.go @@ -29,15 +29,15 @@ func (handler *Handler) webhookExecute(w http.ResponseWriter, r *http.Request) * webhookToken, err := request.RetrieveRouteVariableValue(r, "token") if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Invalid service id parameter", err} + return httperror.InternalServerError("Invalid service id parameter", err) } webhook, err := handler.DataStore.Webhook().WebhookByToken(webhookToken) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a webhook with this token", err} + return httperror.NotFound("Unable to find a webhook with this token", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve webhook from the database", err} + return httperror.InternalServerError("Unable to retrieve webhook from the database", err) } resourceID := webhook.ResourceID @@ -47,9 +47,9 @@ func (handler *Handler) webhookExecute(w http.ResponseWriter, r *http.Request) * endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an environment with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err) } imageTag, _ := request.RetrieveQueryParameter(r, "tag", true) @@ -58,7 +58,7 @@ func (handler *Handler) webhookExecute(w http.ResponseWriter, r *http.Request) * case portainer.ServiceWebhook: return handler.executeServiceWebhook(w, endpoint, resourceID, registryID, imageTag) default: - return &httperror.HandlerError{http.StatusInternalServerError, "Unsupported webhook type", errors.New("Webhooks for this resource are not currently supported")} + return httperror.InternalServerError("Unsupported webhook type", errors.New("Webhooks for this resource are not currently supported")) } } @@ -71,13 +71,13 @@ func (handler *Handler) executeServiceWebhook( ) *httperror.HandlerError { dockerClient, err := handler.DockerClientFactory.CreateClient(endpoint, "", nil) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Error creating docker client", err} + return httperror.InternalServerError("Error creating docker client", err) } defer dockerClient.Close() service, _, err := dockerClient.ServiceInspectWithRaw(context.Background(), resourceID, dockertypes.ServiceInspectOptions{InsertDefaults: true}) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Error looking up service", err} + return httperror.InternalServerError("Error looking up service", err) } service.Spec.TaskTemplate.ForceUpdate++ @@ -101,21 +101,21 @@ func (handler *Handler) executeServiceWebhook( if registryID != 0 { registry, err := handler.DataStore.Registry().Registry(registryID) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Error getting registry", err} + return httperror.InternalServerError("Error getting registry", err) } if registry.Authentication { registryutils.EnsureRegTokenValid(handler.DataStore, registry) serviceUpdateOptions.EncodedRegistryAuth, err = registryutils.GetRegistryAuthHeader(registry) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Error getting registry auth header", err} + return httperror.InternalServerError("Error getting registry auth header", err) } } } if imageTag != "" { rc, err := dockerClient.ImagePull(context.Background(), service.Spec.TaskTemplate.ContainerSpec.Image, dockertypes.ImagePullOptions{RegistryAuth: serviceUpdateOptions.EncodedRegistryAuth}) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusNotFound, Message: "Error pulling image with the specified tag", Err: err} + return httperror.NotFound("Error pulling image with the specified tag", err) } defer func(rc io.ReadCloser) { _ = rc.Close() @@ -124,7 +124,7 @@ func (handler *Handler) executeServiceWebhook( _, err = dockerClient.ServiceUpdate(context.Background(), resourceID, service.Version, service.Spec, serviceUpdateOptions) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Error updating service", err} + return httperror.InternalServerError("Error updating service", err) } return response.Empty(w) } diff --git a/api/http/handler/webhooks/webhook_list.go b/api/http/handler/webhooks/webhook_list.go index 46ef0a18d..966611010 100644 --- a/api/http/handler/webhooks/webhook_list.go +++ b/api/http/handler/webhooks/webhook_list.go @@ -31,12 +31,12 @@ func (handler *Handler) webhookList(w http.ResponseWriter, r *http.Request) *htt var filters webhookListOperationFilters err := request.RetrieveJSONQueryParameter(r, "filters", &filters, true) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: filters", err} + return httperror.BadRequest("Invalid query parameter: filters", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve user info from request context", Err: err} + return httperror.InternalServerError("Unable to retrieve user info from request context", err) } if !securityContext.IsAdmin { return response.JSON(w, []portainer.Webhook{}) @@ -45,7 +45,7 @@ func (handler *Handler) webhookList(w http.ResponseWriter, r *http.Request) *htt webhooks, err := handler.DataStore.Webhook().Webhooks() webhooks = filterWebhooks(webhooks, &filters) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve webhooks from the database", err} + return httperror.InternalServerError("Unable to retrieve webhooks from the database", err) } return response.JSON(w, webhooks) diff --git a/api/http/handler/webhooks/webhook_update.go b/api/http/handler/webhooks/webhook_update.go index 0fff1ec82..089036ae6 100644 --- a/api/http/handler/webhooks/webhook_update.go +++ b/api/http/handler/webhooks/webhook_update.go @@ -37,41 +37,41 @@ func (payload *webhookUpdatePayload) Validate(r *http.Request) error { func (handler *Handler) webhookUpdate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { id, err := request.RetrieveNumericRouteVariableValue(r, "id") if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid webhook id", err} + return httperror.BadRequest("Invalid webhook id", err) } webhookID := portainer.WebhookID(id) var payload webhookUpdatePayload err = request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + return httperror.BadRequest("Invalid request payload", err) } webhook, err := handler.DataStore.Webhook().Webhook(webhookID) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find a webhooks with the specified identifier inside the database", err} + return httperror.NotFound("Unable to find a webhooks with the specified identifier inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a webhooks with the specified identifier inside the database", err} + return httperror.InternalServerError("Unable to find a webhooks with the specified identifier inside the database", err) } securityContext, err := security.RetrieveRestrictedRequestContext(r) if err != nil { - return &httperror.HandlerError{StatusCode: http.StatusInternalServerError, Message: "Unable to retrieve user info from request context", Err: err} + return httperror.InternalServerError("Unable to retrieve user info from request context", err) } if !securityContext.IsAdmin { - return &httperror.HandlerError{StatusCode: http.StatusForbidden, Message: "Not authorized to update a webhook", Err: errors.New("not authorized to update a webhook")} + return httperror.Forbidden("Not authorized to update a webhook", errors.New("not authorized to update a webhook")) } if payload.RegistryID != 0 { tokenData, err := security.RetrieveTokenData(r) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user authentication token", err} + return httperror.InternalServerError("Unable to retrieve user authentication token", err) } _, err = access.GetAccessibleRegistry(handler.DataStore, tokenData.ID, webhook.EndpointID, payload.RegistryID) if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission deny to access registry", err} + return httperror.Forbidden("Permission deny to access registry", err) } } @@ -79,7 +79,7 @@ func (handler *Handler) webhookUpdate(w http.ResponseWriter, r *http.Request) *h err = handler.DataStore.Webhook().UpdateWebhook(portainer.WebhookID(id), webhook) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist the webhook inside the database", err} + return httperror.InternalServerError("Unable to persist the webhook inside the database", err) } return response.JSON(w, webhook) diff --git a/api/http/handler/websocket/attach.go b/api/http/handler/websocket/attach.go index f7a95e9ef..0c137d290 100644 --- a/api/http/handler/websocket/attach.go +++ b/api/http/handler/websocket/attach.go @@ -35,27 +35,27 @@ import ( func (handler *Handler) websocketAttach(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { attachID, err := request.RetrieveQueryParameter(r, "id", false) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: id", err} + return httperror.BadRequest("Invalid query parameter: id", err) } if !govalidator.IsHexadecimal(attachID) { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: id (must be hexadecimal identifier)", err} + return httperror.BadRequest("Invalid query parameter: id (must be hexadecimal identifier)", err) } endpointID, err := request.RetrieveNumericQueryParameter(r, "endpointId", false) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: endpointId", err} + return httperror.BadRequest("Invalid query parameter: endpointId", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find the environment associated to the stack inside the database", err} + return httperror.NotFound("Unable to find the environment associated to the stack inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find the environment associated to the stack inside the database", err} + return httperror.InternalServerError("Unable to find the environment associated to the stack inside the database", err) } err = handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access environment", err} + return httperror.Forbidden("Permission denied to access environment", err) } params := &webSocketRequestParams{ @@ -66,7 +66,7 @@ func (handler *Handler) websocketAttach(w http.ResponseWriter, r *http.Request) err = handler.handleAttachRequest(w, r, params) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "An error occured during websocket attach operation", err} + return httperror.InternalServerError("An error occured during websocket attach operation", err) } return nil diff --git a/api/http/handler/websocket/exec.go b/api/http/handler/websocket/exec.go index b089d92ed..5d412d752 100644 --- a/api/http/handler/websocket/exec.go +++ b/api/http/handler/websocket/exec.go @@ -41,27 +41,27 @@ type execStartOperationPayload struct { func (handler *Handler) websocketExec(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { execID, err := request.RetrieveQueryParameter(r, "id", false) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: id", err} + return httperror.BadRequest("Invalid query parameter: id", err) } if !govalidator.IsHexadecimal(execID) { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: id (must be hexadecimal identifier)", err} + return httperror.BadRequest("Invalid query parameter: id (must be hexadecimal identifier)", err) } endpointID, err := request.RetrieveNumericQueryParameter(r, "endpointId", false) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: endpointId", err} + return httperror.BadRequest("Invalid query parameter: endpointId", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find the environment associated to the stack inside the database", err} + return httperror.NotFound("Unable to find the environment associated to the stack inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find the environment associated to the stack inside the database", err} + return httperror.InternalServerError("Unable to find the environment associated to the stack inside the database", err) } err = handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access environment", err} + return httperror.Forbidden("Permission denied to access environment", err) } params := &webSocketRequestParams{ @@ -72,7 +72,7 @@ func (handler *Handler) websocketExec(w http.ResponseWriter, r *http.Request) *h err = handler.handleExecRequest(w, r, params) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "An error occured during websocket exec operation", err} + return httperror.InternalServerError("An error occured during websocket exec operation", err) } return nil diff --git a/api/http/handler/websocket/pod.go b/api/http/handler/websocket/pod.go index 07ff1a8f2..5832e4439 100644 --- a/api/http/handler/websocket/pod.go +++ b/api/http/handler/websocket/pod.go @@ -39,44 +39,44 @@ import ( func (handler *Handler) websocketPodExec(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericQueryParameter(r, "endpointId", false) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: endpointId", err} + return httperror.BadRequest("Invalid query parameter: endpointId", err) } namespace, err := request.RetrieveQueryParameter(r, "namespace", false) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: namespace", err} + return httperror.BadRequest("Invalid query parameter: namespace", err) } podName, err := request.RetrieveQueryParameter(r, "podName", false) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: podName", err} + return httperror.BadRequest("Invalid query parameter: podName", err) } containerName, err := request.RetrieveQueryParameter(r, "containerName", false) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: containerName", err} + return httperror.BadRequest("Invalid query parameter: containerName", err) } command, err := request.RetrieveQueryParameter(r, "command", false) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: command", err} + return httperror.BadRequest("Invalid query parameter: command", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find the environment associated to the stack inside the database", err} + return httperror.NotFound("Unable to find the environment associated to the stack inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find the environment associated to the stack inside the database", err} + return httperror.InternalServerError("Unable to find the environment associated to the stack inside the database", err) } err = handler.requestBouncer.AuthorizedEndpointOperation(r, endpoint) if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access environment", err} + return httperror.Forbidden("Permission denied to access environment", err) } serviceAccountToken, isAdminToken, err := handler.getToken(r, endpoint, false) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to get user service account token", err} + return httperror.InternalServerError("Unable to get user service account token", err) } params := &webSocketRequestParams{ @@ -89,20 +89,20 @@ func (handler *Handler) websocketPodExec(w http.ResponseWriter, r *http.Request) if endpoint.Type == portainer.AgentOnKubernetesEnvironment { err := handler.proxyAgentWebsocketRequest(w, r, params) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to proxy websocket request to agent", err} + return httperror.InternalServerError("Unable to proxy websocket request to agent", err) } return nil } else if endpoint.Type == portainer.EdgeAgentOnKubernetesEnvironment { err := handler.proxyEdgeAgentWebsocketRequest(w, r, params) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to proxy websocket request to Edge agent", err} + return httperror.InternalServerError("Unable to proxy websocket request to Edge agent", err) } return nil } cli, err := handler.KubernetesClientFactory.GetKubeClient(endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to create Kubernetes client", err} + return httperror.InternalServerError("Unable to create Kubernetes client", err) } handlerErr := handler.hijackPodExecStartOperation(w, r, cli, serviceAccountToken, isAdminToken, endpoint, namespace, podName, containerName, command) @@ -126,7 +126,7 @@ func (handler *Handler) hijackPodExecStartOperation( websocketConn, err := handler.connectionUpgrader.Upgrade(w, r, nil) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to upgrade the connection", err} + return httperror.InternalServerError("Unable to upgrade the connection", err) } defer websocketConn.Close() @@ -153,7 +153,7 @@ func (handler *Handler) hijackPodExecStartOperation( return nil } - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to start exec process inside container", err} + return httperror.InternalServerError("Unable to start exec process inside container", err) } func (handler *Handler) getToken(request *http.Request, endpoint *portainer.Endpoint, setLocalAdminToken bool) (string, bool, error) { diff --git a/api/http/handler/websocket/shell_pod.go b/api/http/handler/websocket/shell_pod.go index eb6d1a08d..e6e498e1a 100644 --- a/api/http/handler/websocket/shell_pod.go +++ b/api/http/handler/websocket/shell_pod.go @@ -27,39 +27,39 @@ import ( func (handler *Handler) websocketShellPodExec(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { endpointID, err := request.RetrieveNumericQueryParameter(r, "endpointId", false) if err != nil { - return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: endpointId", err} + return httperror.BadRequest("Invalid query parameter: endpointId", err) } endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID)) if handler.DataStore.IsErrObjectNotFound(err) { - return &httperror.HandlerError{http.StatusNotFound, "Unable to find the environment associated to the stack inside the database", err} + return httperror.NotFound("Unable to find the environment associated to the stack inside the database", err) } else if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find the environment associated to the stack inside the database", err} + return httperror.InternalServerError("Unable to find the environment associated to the stack inside the database", err) } tokenData, err := security.RetrieveTokenData(r) if err != nil { - return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access environment", err} + return httperror.Forbidden("Permission denied to access environment", err) } cli, err := handler.KubernetesClientFactory.GetKubeClient(endpoint) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to create Kubernetes client", err} + return httperror.InternalServerError("Unable to create Kubernetes client", err) } serviceAccount, err := cli.GetServiceAccount(tokenData) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find serviceaccount associated with user", err} + return httperror.InternalServerError("Unable to find serviceaccount associated with user", err) } settings, err := handler.DataStore.Settings().Settings() if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable read settings", err} + return httperror.InternalServerError("Unable read settings", err) } shellPod, err := cli.CreateUserShellPod(r.Context(), serviceAccount.Name, settings.KubectlShellImage) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to create user shell", err} + return httperror.InternalServerError("Unable to create user shell", err) } // Modifying request params mid-flight before forewarding to K8s API server (websocket) @@ -87,13 +87,13 @@ func (handler *Handler) websocketShellPodExec(w http.ResponseWriter, r *http.Req if endpoint.Type == portainer.AgentOnKubernetesEnvironment { err := handler.proxyAgentWebsocketRequest(w, r, params) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to proxy websocket request to agent", err} + return httperror.InternalServerError("Unable to proxy websocket request to agent", err) } return nil } else if endpoint.Type == portainer.EdgeAgentOnKubernetesEnvironment { err := handler.proxyEdgeAgentWebsocketRequest(w, r, params) if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to proxy websocket request to Edge agent", err} + return httperror.InternalServerError("Unable to proxy websocket request to Edge agent", err) } return nil }