refactor(errors): reorganize errors (#3938)

* refactor(bolt): move ErrObjectNotFound to bolt

* refactor(http): move ErrUnauthorized to http package

* refactor(http): move ErrResourceAccessDenied to http errors

* refactor(http): move security errors to package

* refactor(users): move user errors to users package

* refactor(errors): move single errors to their package

* refactor(schedules): move schedule error to package

* refactor(http): move endpoint error to http package

* refactor(docker): move docker errors to package

* refactor(filesystem): move filesystem errors to package

* refactor(errors): remove portainer.Error

* style(chisel): reorder imports

* fix(stacks): remove portainer.Error
pull/4016/head
Chaim Lev-Ari 2020-07-08 00:57:52 +03:00 committed by GitHub
parent e82833a363
commit db4a5292be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
121 changed files with 550 additions and 477 deletions

View File

@ -15,6 +15,7 @@ import (
"github.com/portainer/portainer/api/bolt/endpoint"
"github.com/portainer/portainer/api/bolt/endpointgroup"
"github.com/portainer/portainer/api/bolt/endpointrelation"
"github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/bolt/extension"
"github.com/portainer/portainer/api/bolt/migrator"
"github.com/portainer/portainer/api/bolt/registry"
@ -123,7 +124,7 @@ func (store *Store) MigrateData() error {
}
version, err := store.VersionService.DBVersion()
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
version = 0
} else if err != nil {
return err

View File

@ -0,0 +1,7 @@
package errors
import "errors"
var (
ErrObjectNotFound = errors.New("Object not found inside the database")
)

View File

@ -2,13 +2,14 @@ package bolt
import (
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/internal/authorization"
)
// Init creates the default data set.
func (store *Store) Init() error {
_, err := store.SettingsService.Settings()
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
defaultSettings := &portainer.Settings{
AuthenticationMethod: portainer.AuthenticationInternal,
BlackListedLabels: make([]portainer.Pair, 0),
@ -42,7 +43,7 @@ func (store *Store) Init() error {
}
_, err = store.DockerHubService.DockerHub()
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
defaultDockerHub := &portainer.DockerHub{
Authentication: false,
Username: "",

View File

@ -4,7 +4,7 @@ import (
"encoding/binary"
"github.com/boltdb/bolt"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
)
// Itob returns an 8-byte big endian representation of v.
@ -36,7 +36,7 @@ func GetObject(db *bolt.DB, bucketName string, key []byte, object interface{}) e
value := bucket.Get(key)
if value == nil {
return portainer.ErrObjectNotFound
return errors.ErrObjectNotFound
}
data = make([]byte, len(value))

View File

@ -3,6 +3,7 @@ package migrator
import (
"github.com/boltdb/bolt"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/bolt/user"
)
@ -22,7 +23,7 @@ func (m *Migrator) updateAdminUserToDBVersion1() error {
if err != nil {
return err
}
} else if err != nil && err != portainer.ErrObjectNotFound {
} else if err != nil && err != errors.ErrObjectNotFound {
return err
}
return nil

View File

@ -2,6 +2,7 @@ package stack
import (
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/bolt/internal"
"github.com/boltdb/bolt"
@ -64,7 +65,7 @@ func (service *Service) StackByName(name string) (*portainer.Stack, error) {
}
if stack == nil {
return portainer.ErrObjectNotFound
return errors.ErrObjectNotFound
}
return nil

View File

@ -2,6 +2,7 @@ package team
import (
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/bolt/internal"
"github.com/boltdb/bolt"
@ -64,7 +65,7 @@ func (service *Service) TeamByName(name string) (*portainer.Team, error) {
}
if team == nil {
return portainer.ErrObjectNotFound
return errors.ErrObjectNotFound
}
return nil

View File

@ -2,6 +2,7 @@ package user
import (
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/bolt/internal"
"github.com/boltdb/bolt"
@ -64,7 +65,7 @@ func (service *Service) UserByUsername(username string) (*portainer.User, error)
}
if user == nil {
return portainer.ErrObjectNotFound
return errors.ErrObjectNotFound
}
return nil
})

View File

@ -4,7 +4,7 @@ import (
"strconv"
"github.com/boltdb/bolt"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/bolt/internal"
)
@ -40,7 +40,7 @@ func (service *Service) DBVersion() (int, error) {
value := bucket.Get([]byte(versionKey))
if value == nil {
return portainer.ErrObjectNotFound
return errors.ErrObjectNotFound
}
data = make([]byte, len(value))

View File

@ -2,6 +2,7 @@ package webhook
import (
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/bolt/internal"
"github.com/boltdb/bolt"
@ -87,7 +88,7 @@ func (service *Service) WebhookByResourceID(ID string) (*portainer.Webhook, erro
}
if webhook == nil {
return portainer.ErrObjectNotFound
return errors.ErrObjectNotFound
}
return nil
@ -118,7 +119,7 @@ func (service *Service) WebhookByToken(token string) (*portainer.Webhook, error)
}
if webhook == nil {
return portainer.ErrObjectNotFound
return errors.ErrObjectNotFound
}
return nil

View File

@ -7,11 +7,10 @@ import (
"time"
"github.com/dchest/uniuri"
cmap "github.com/orcaman/concurrent-map"
chserver "github.com/jpillora/chisel/server"
portainer "github.com/portainer/portainer/api"
cmap "github.com/orcaman/concurrent-map"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
)
const (
@ -88,7 +87,7 @@ func (service *Service) retrievePrivateKeySeed() (string, error) {
var serverInfo *portainer.TunnelServerInfo
serverInfo, err := service.dataStore.TunnelServer().Info()
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
keySeed := uniuri.NewLen(16)
serverInfo = &portainer.TunnelServerInfo{

View File

@ -1,6 +1,7 @@
package cli
import (
"errors"
"time"
"github.com/portainer/portainer/api"
@ -15,11 +16,11 @@ import (
// Service implements the CLIService interface
type Service struct{}
const (
errInvalidEndpointProtocol = portainer.Error("Invalid endpoint protocol: Portainer only supports unix://, npipe:// or tcp://")
errSocketOrNamedPipeNotFound = portainer.Error("Unable to locate Unix socket or named pipe")
errInvalidSnapshotInterval = portainer.Error("Invalid snapshot interval")
errAdminPassExcludeAdminPassFile = portainer.Error("Cannot use --admin-password with --admin-password-file")
var (
errInvalidEndpointProtocol = errors.New("Invalid endpoint protocol: Portainer only supports unix://, npipe:// or tcp://")
errSocketOrNamedPipeNotFound = errors.New("Unable to locate Unix socket or named pipe")
errInvalidSnapshotInterval = errors.New("Invalid snapshot interval")
errAdminPassExcludeAdminPassFile = errors.New("Cannot use --admin-password with --admin-password-file")
)
// ParseFlags parse the CLI flags and return a portainer.Flags struct

View File

@ -1,6 +1,7 @@
package docker
import (
"errors"
"fmt"
"net/http"
"strings"
@ -11,8 +12,9 @@ import (
"github.com/portainer/portainer/api/crypto"
)
var errUnsupportedEnvironmentType = errors.New("Environment not supported")
const (
unsupportedEnvironmentType = portainer.Error("Environment not supported")
defaultDockerRequestTimeout = 60
dockerClientVersion = "1.37"
)
@ -36,7 +38,7 @@ func NewClientFactory(signatureService portainer.DigitalSignatureService, revers
// with an agent enabled endpoint to target a specific node in an agent cluster.
func (factory *ClientFactory) CreateClient(endpoint *portainer.Endpoint, nodeName string) (*client.Client, error) {
if endpoint.Type == portainer.AzureEnvironment {
return nil, unsupportedEnvironmentType
return nil, errUnsupportedEnvironmentType
} else if endpoint.Type == portainer.AgentOnDockerEnvironment {
return createAgentClient(endpoint, factory.signatureService, nodeName)
} else if endpoint.Type == portainer.EdgeAgentOnDockerEnvironment {

8
api/docker/errors.go Normal file
View File

@ -0,0 +1,8 @@
package docker
import "errors"
// Docker errors
var (
ErrUnableToPingEndpoint = errors.New("Unable to communicate with the endpoint")
)

View File

@ -1,117 +0,0 @@
package portainer
// General errors.
const (
ErrUnauthorized = Error("Unauthorized")
ErrResourceAccessDenied = Error("Access denied to resource")
ErrAuthorizationRequired = Error("Authorization required for this operation")
ErrObjectNotFound = Error("Object not found inside the database")
ErrMissingSecurityContext = Error("Unable to find security details in request context")
)
// User errors.
const (
ErrUserAlreadyExists = Error("User already exists")
ErrInvalidUsername = Error("Invalid username. White spaces are not allowed")
ErrAdminAlreadyInitialized = Error("An administrator user already exists")
ErrAdminCannotRemoveSelf = Error("Cannot remove your own user account. Contact another administrator")
ErrCannotRemoveLastLocalAdmin = Error("Cannot remove the last local administrator account")
)
// Team errors.
const (
ErrTeamAlreadyExists = Error("Team already exists")
)
// TeamMembership errors.
const (
ErrTeamMembershipAlreadyExists = Error("Team membership already exists for this user and team")
)
// ResourceControl errors.
const (
ErrResourceControlAlreadyExists = Error("A resource control is already applied on this resource")
ErrInvalidResourceControlType = Error("Unsupported resource control type")
)
// Endpoint errors.
const (
ErrEndpointAccessDenied = Error("Access denied to endpoint")
)
// Azure environment errors
const (
ErrAzureInvalidCredentials = Error("Invalid Azure credentials")
)
// Endpoint group errors.
const (
ErrCannotRemoveDefaultGroup = Error("Cannot remove the default endpoint group")
)
// Registry errors.
const (
ErrRegistryAlreadyExists = Error("A registry is already defined for this URL")
)
// Stack errors
const (
ErrStackAlreadyExists = Error("A stack already exists with this name")
ErrComposeFileNotFoundInRepository = Error("Unable to find a Compose file in the repository")
ErrStackNotExternal = Error("Not an external stack")
)
// Tag errors
const (
ErrTagAlreadyExists = Error("A tag already exists with this name")
)
// Endpoint extensions error
const (
ErrEndpointExtensionNotSupported = Error("This extension is not supported")
ErrEndpointExtensionAlreadyAssociated = Error("This extension is already associated to the endpoint")
)
// Crypto errors.
const (
ErrCryptoHashFailure = Error("Unable to hash data")
)
// JWT errors.
const (
ErrSecretGeneration = Error("Unable to generate secret key")
ErrInvalidJWTToken = Error("Invalid JWT token")
ErrMissingContextData = Error("Unable to find JWT data in request context")
)
// File errors.
const (
ErrUndefinedTLSFileType = Error("Undefined TLS file type")
)
// Extension errors.
const (
ErrExtensionAlreadyEnabled = Error("This extension is already enabled")
)
// Docker errors.
const (
ErrUnableToPingEndpoint = Error("Unable to communicate with the endpoint")
)
// Schedule errors.
const (
ErrHostManagementFeaturesDisabled = Error("Host management features are disabled")
)
// Error represents an application error.
type Error string
// Error returns the error message.
func (e Error) Error() string { return string(e) }
// Webhook errors
const (
ErrWebhookAlreadyExists = Error("A webhook for this resource already exists")
ErrUnsupportedWebhookType = Error("Webhooks for this resource are not currently supported")
)

View File

@ -3,6 +3,7 @@ package exec
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"os"
"os/exec"
@ -103,7 +104,7 @@ func runCommandAndCaptureStdErr(command string, args []string, env []string, wor
err := cmd.Run()
if err != nil {
return portainer.Error(stderr.String())
return errors.New(stderr.String())
}
return nil

View File

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"io/ioutil"
@ -50,6 +51,9 @@ const (
TempPath = "tmp"
)
// ErrUndefinedTLSFileType represents an error returned on undefined TLS file type
var ErrUndefinedTLSFileType = errors.New("Undefined TLS file type")
// Service represents a service for managing files and directories.
type Service struct {
dataStorePath string
@ -194,7 +198,7 @@ func (service *Service) StoreTLSFileFromBytes(folder string, fileType portainer.
case portainer.TLSFileKey:
fileName = TLSKeyFile
default:
return "", portainer.ErrUndefinedTLSFileType
return "", ErrUndefinedTLSFileType
}
tlsFilePath := path.Join(storePath, fileName)
@ -217,7 +221,7 @@ func (service *Service) GetPathForTLSFile(folder string, fileType portainer.TLSF
case portainer.TLSFileKey:
fileName = TLSKeyFile
default:
return "", portainer.ErrUndefinedTLSFileType
return "", ErrUndefinedTLSFileType
}
return path.Join(service.fileStorePath, TLSStorePath, folder, fileName), nil
}
@ -243,7 +247,7 @@ func (service *Service) DeleteTLSFile(folder string, fileType portainer.TLSFileT
case portainer.TLSFileKey:
fileName = TLSKeyFile
default:
return portainer.ErrUndefinedTLSFileType
return ErrUndefinedTLSFileType
}
filePath := path.Join(service.fileStorePath, TLSStorePath, folder, fileName)

View File

@ -3,6 +3,7 @@ package client
import (
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
@ -14,9 +15,10 @@ import (
"github.com/portainer/portainer/api"
)
var errInvalidResponseStatus = errors.New("Invalid response status (expecting 200)")
const (
errInvalidResponseStatus = portainer.Error("Invalid response status (expecting 200)")
defaultHTTPTimeout = 5
defaultHTTPTimeout = 5
)
// HTTPClient represents a client to send HTTP requests.
@ -56,7 +58,7 @@ func (client *HTTPClient) ExecuteAzureAuthenticationRequest(credentials *portain
}
if response.StatusCode != http.StatusOK {
return nil, portainer.ErrAzureInvalidCredentials
return nil, errors.New("Invalid Azure credentials")
}
var token AzureAuthenticationResponse

12
api/http/errors/errors.go Normal file
View File

@ -0,0 +1,12 @@
package errors
import "errors"
var (
// ErrEndpointAccessDenied Access denied to endpoint error
ErrEndpointAccessDenied = errors.New("Access denied to endpoint")
// ErrUnauthorized Unauthorized error
ErrUnauthorized = errors.New("Unauthorized")
// ErrResourceAccessDenied Access denied to resource error
ErrResourceAccessDenied = errors.New("Access denied to resource")
)

View File

@ -1,6 +1,7 @@
package auth
import (
"errors"
"log"
"net/http"
"strings"
@ -10,6 +11,8 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
httperrors "github.com/portainer/portainer/api/http/errors"
"github.com/portainer/portainer/api/internal/authorization"
)
@ -24,10 +27,10 @@ type authenticateResponse struct {
func (payload *authenticatePayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.Username) {
return portainer.Error("Invalid username")
return errors.New("Invalid username")
}
if govalidator.IsNull(payload.Password) {
return portainer.Error("Invalid password")
return errors.New("Invalid password")
}
return nil
}
@ -45,19 +48,19 @@ func (handler *Handler) authenticate(w http.ResponseWriter, r *http.Request) *ht
}
u, err := handler.DataStore.User().UserByUsername(payload.Username)
if err != nil && err != portainer.ErrObjectNotFound {
if err != nil && err != bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve a user with the specified username from the database", err}
}
if err == portainer.ErrObjectNotFound && (settings.AuthenticationMethod == portainer.AuthenticationInternal || settings.AuthenticationMethod == portainer.AuthenticationOAuth) {
return &httperror.HandlerError{http.StatusUnprocessableEntity, "Invalid credentials", portainer.ErrUnauthorized}
if err == bolterrors.ErrObjectNotFound && (settings.AuthenticationMethod == portainer.AuthenticationInternal || settings.AuthenticationMethod == portainer.AuthenticationOAuth) {
return &httperror.HandlerError{http.StatusUnprocessableEntity, "Invalid credentials", httperrors.ErrUnauthorized}
}
if settings.AuthenticationMethod == portainer.AuthenticationLDAP {
if u == nil && settings.LDAPSettings.AutoCreateUsers {
return handler.authenticateLDAPAndCreateUser(w, payload.Username, payload.Password, &settings.LDAPSettings)
} else if u == nil && !settings.LDAPSettings.AutoCreateUsers {
return &httperror.HandlerError{http.StatusUnprocessableEntity, "Invalid credentials", portainer.ErrUnauthorized}
return &httperror.HandlerError{http.StatusUnprocessableEntity, "Invalid credentials", httperrors.ErrUnauthorized}
}
return handler.authenticateLDAP(w, u, payload.Password, &settings.LDAPSettings)
}
@ -87,7 +90,7 @@ func (handler *Handler) authenticateLDAP(w http.ResponseWriter, user *portainer.
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", portainer.ErrUnauthorized}
return &httperror.HandlerError{http.StatusUnprocessableEntity, "Invalid credentials", httperrors.ErrUnauthorized}
}
return handler.writeToken(w, user)

View File

@ -2,7 +2,7 @@ package auth
import (
"encoding/json"
"github.com/portainer/portainer/api/internal/authorization"
"errors"
"io/ioutil"
"log"
"net/http"
@ -11,6 +11,9 @@ import (
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
httperrors "github.com/portainer/portainer/api/http/errors"
"github.com/portainer/portainer/api/internal/authorization"
)
type oauthPayload struct {
@ -19,7 +22,7 @@ type oauthPayload struct {
func (payload *oauthPayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.Code) {
return portainer.Error("Invalid OAuth authorization code")
return errors.New("Invalid OAuth authorization code")
}
return nil
}
@ -66,7 +69,7 @@ func (handler *Handler) authenticateThroughExtension(code, licenseKey string, se
}
if resp.StatusCode != http.StatusOK {
return "", portainer.Error(extResp.Err + ":" + extResp.Details)
return "", errors.New(extResp.Err + ":" + extResp.Details)
}
return extResp.Username, nil
@ -85,11 +88,11 @@ func (handler *Handler) validateOAuth(w http.ResponseWriter, r *http.Request) *h
}
if settings.AuthenticationMethod != 3 {
return &httperror.HandlerError{http.StatusForbidden, "OAuth authentication is not enabled", portainer.Error("OAuth authentication is not enabled")}
return &httperror.HandlerError{http.StatusForbidden, "OAuth authentication is not enabled", errors.New("OAuth authentication is not enabled")}
}
extension, err := handler.DataStore.Extension().Extension(portainer.OAuthAuthenticationExtension)
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Oauth authentication extension is not enabled", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a extension with the specified identifier inside the database", err}
@ -98,16 +101,16 @@ func (handler *Handler) validateOAuth(w http.ResponseWriter, r *http.Request) *h
username, err := handler.authenticateThroughExtension(payload.Code, extension.License.LicenseKey, &settings.OAuthSettings)
if err != nil {
log.Printf("[DEBUG] - OAuth authentication error: %s", err)
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to authenticate through OAuth", portainer.ErrUnauthorized}
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to authenticate through OAuth", httperrors.ErrUnauthorized}
}
user, err := handler.DataStore.User().UserByUsername(username)
if err != nil && err != portainer.ErrObjectNotFound {
if err != nil && err != bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve a user with the specified username from the database", err}
}
if user == nil && !settings.OAuthSettings.OAuthAutoCreateUsers {
return &httperror.HandlerError{http.StatusForbidden, "Account not created beforehand in Portainer and automatic user provisioning not enabled", portainer.ErrUnauthorized}
return &httperror.HandlerError{http.StatusForbidden, "Account not created beforehand in Portainer and automatic user provisioning not enabled", httperrors.ErrUnauthorized}
}
if user == nil {

View File

@ -1,6 +1,7 @@
package dockerhub
import (
"errors"
"net/http"
"github.com/asaskevich/govalidator"
@ -18,7 +19,7 @@ type dockerhubUpdatePayload struct {
func (payload *dockerhubUpdatePayload) Validate(r *http.Request) error {
if payload.Authentication && (govalidator.IsNull(payload.Username) || govalidator.IsNull(payload.Password)) {
return portainer.Error("Invalid credentials. Username and password must be specified when authentication is enabled")
return errors.New("Invalid credentials. Username and password must be specified when authentication is enabled")
}
return nil
}

View File

@ -1,6 +1,7 @@
package edgegroups
import (
"errors"
"net/http"
"github.com/asaskevich/govalidator"
@ -20,13 +21,13 @@ type edgeGroupCreatePayload struct {
func (payload *edgeGroupCreatePayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.Name) {
return portainer.Error("Invalid Edge group name")
return errors.New("Invalid Edge group name")
}
if payload.Dynamic && (payload.TagIDs == nil || len(payload.TagIDs) == 0) {
return portainer.Error("TagIDs is mandatory for a dynamic Edge group")
return errors.New("TagIDs is mandatory for a dynamic Edge group")
}
if !payload.Dynamic && (payload.Endpoints == nil || len(payload.Endpoints) == 0) {
return portainer.Error("Endpoints is mandatory for a static Edge group")
return errors.New("Endpoints is mandatory for a static Edge group")
}
return nil
}
@ -45,7 +46,7 @@ func (handler *Handler) edgeGroupCreate(w http.ResponseWriter, r *http.Request)
for _, edgeGroup := range edgeGroups {
if edgeGroup.Name == payload.Name {
return &httperror.HandlerError{http.StatusBadRequest, "Edge group name must be unique", portainer.Error("Edge group name must be unique")}
return &httperror.HandlerError{http.StatusBadRequest, "Edge group name must be unique", errors.New("Edge group name must be unique")}
}
}

View File

@ -1,12 +1,14 @@
package edgegroups
import (
"errors"
"net/http"
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
portainer "github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
)
func (handler *Handler) edgeGroupDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
@ -16,7 +18,7 @@ func (handler *Handler) edgeGroupDelete(w http.ResponseWriter, r *http.Request)
}
_, err = handler.DataStore.EdgeGroup().EdgeGroup(portainer.EdgeGroupID(edgeGroupID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}
@ -30,7 +32,7 @@ func (handler *Handler) edgeGroupDelete(w http.ResponseWriter, r *http.Request)
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", portainer.Error("Edge group is used by an Edge stack")}
return &httperror.HandlerError{http.StatusForbidden, "Edge group is used by an Edge stack", errors.New("Edge group is used by an Edge stack")}
}
}
}

View File

@ -7,6 +7,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
)
func (handler *Handler) edgeGroupInspect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
@ -16,7 +17,7 @@ func (handler *Handler) edgeGroupInspect(w http.ResponseWriter, r *http.Request)
}
edgeGroup, err := handler.DataStore.EdgeGroup().EdgeGroup(portainer.EdgeGroupID(edgeGroupID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}

View File

@ -1,6 +1,7 @@
package edgegroups
import (
"errors"
"net/http"
"github.com/asaskevich/govalidator"
@ -8,6 +9,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/internal/edge"
)
@ -21,13 +23,13 @@ type edgeGroupUpdatePayload struct {
func (payload *edgeGroupUpdatePayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.Name) {
return portainer.Error("Invalid Edge group name")
return errors.New("Invalid Edge group name")
}
if payload.Dynamic && (payload.TagIDs == nil || len(payload.TagIDs) == 0) {
return portainer.Error("TagIDs is mandatory for a dynamic Edge group")
return errors.New("TagIDs is mandatory for a dynamic Edge group")
}
if !payload.Dynamic && (payload.Endpoints == nil || len(payload.Endpoints) == 0) {
return portainer.Error("Endpoints is mandatory for a static Edge group")
return errors.New("Endpoints is mandatory for a static Edge group")
}
return nil
}
@ -45,7 +47,7 @@ func (handler *Handler) edgeGroupUpdate(w http.ResponseWriter, r *http.Request)
}
edgeGroup, err := handler.DataStore.EdgeGroup().EdgeGroup(portainer.EdgeGroupID(edgeGroupID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}
@ -58,7 +60,7 @@ func (handler *Handler) edgeGroupUpdate(w http.ResponseWriter, r *http.Request)
}
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", portainer.Error("Edge group name must be unique")}
return &httperror.HandlerError{http.StatusBadRequest, "Edge group name must be unique", errors.New("Edge group name must be unique")}
}
}

View File

@ -41,7 +41,7 @@ type edgeJobCreateFromFileContentPayload struct {
func (payload *edgeJobCreateFromFileContentPayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.Name) {
return portainer.Error("Invalid Edge job name")
return errors.New("Invalid Edge job name")
}
if !govalidator.Matches(payload.Name, `^[a-zA-Z0-9][a-zA-Z0-9_.-]*$`) {
@ -49,15 +49,15 @@ func (payload *edgeJobCreateFromFileContentPayload) Validate(r *http.Request) er
}
if govalidator.IsNull(payload.CronExpression) {
return portainer.Error("Invalid cron expression")
return errors.New("Invalid cron expression")
}
if payload.Endpoints == nil || len(payload.Endpoints) == 0 {
return portainer.Error("Invalid endpoints payload")
return errors.New("Invalid endpoints payload")
}
if govalidator.IsNull(payload.FileContent) {
return portainer.Error("Invalid script file content")
return errors.New("Invalid script file content")
}
return nil
@ -114,7 +114,7 @@ func (payload *edgeJobCreateFromFilePayload) Validate(r *http.Request) error {
file, _, err := request.RetrieveMultiPartFormFile(r, "file")
if err != nil {
return portainer.Error("Invalid script file. Ensure that the file is uploaded correctly")
return errors.New("Invalid script file. Ensure that the file is uploaded correctly")
}
payload.File = file

View File

@ -8,6 +8,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
)
func (handler *Handler) edgeJobDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
@ -17,7 +18,7 @@ func (handler *Handler) edgeJobDelete(w http.ResponseWriter, r *http.Request) *h
}
edgeJob, err := handler.DataStore.EdgeJob().EdgeJob(portainer.EdgeJobID(edgeJobID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}

View File

@ -7,6 +7,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
)
type edgeJobFileResponse struct {
@ -21,7 +22,7 @@ func (handler *Handler) edgeJobFile(w http.ResponseWriter, r *http.Request) *htt
}
edgeJob, err := handler.DataStore.EdgeJob().EdgeJob(portainer.EdgeJobID(edgeJobID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}

View File

@ -3,11 +3,11 @@ package edgejobs
import (
"net/http"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
)
type edgeJobInspectResponse struct {
@ -22,7 +22,7 @@ func (handler *Handler) edgeJobInspect(w http.ResponseWriter, r *http.Request) *
}
edgeJob, err := handler.DataStore.EdgeJob().EdgeJob(portainer.EdgeJobID(edgeJobID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}

View File

@ -8,6 +8,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
)
// DELETE request on /api/edge_jobs/:id/tasks/:taskID/logs
@ -23,7 +24,7 @@ func (handler *Handler) edgeJobTasksClear(w http.ResponseWriter, r *http.Request
}
edgeJob, err := handler.DataStore.EdgeJob().EdgeJob(portainer.EdgeJobID(edgeJobID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}

View File

@ -7,6 +7,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
)
// POST request on /api/edge_jobs/:id/tasks/:taskID/logs
@ -22,7 +23,7 @@ func (handler *Handler) edgeJobTasksCollect(w http.ResponseWriter, r *http.Reque
}
edgeJob, err := handler.DataStore.EdgeJob().EdgeJob(portainer.EdgeJobID(edgeJobID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}

View File

@ -8,6 +8,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
)
type taskContainer struct {
@ -18,22 +19,13 @@ type taskContainer struct {
// GET request on /api/edge_jobs/:id/tasks
func (handler *Handler) edgeJobTasksList(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
settings, err := handler.DataStore.Settings().Settings()
if err != nil {
return &httperror.HandlerError{http.StatusServiceUnavailable, "Unable to retrieve settings", err}
}
if !settings.EnableEdgeComputeFeatures {
return &httperror.HandlerError{http.StatusServiceUnavailable, "Edge compute features are disabled", portainer.ErrHostManagementFeaturesDisabled}
}
edgeJobID, err := request.RetrieveNumericRouteVariableValue(r, "id")
if err != nil {
return &httperror.HandlerError{http.StatusBadRequest, "Invalid Edge job identifier route variable", err}
}
edgeJob, err := handler.DataStore.EdgeJob().EdgeJob(portainer.EdgeJobID(edgeJobID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}

View File

@ -10,6 +10,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
)
type edgeJobUpdatePayload struct {
@ -28,15 +29,6 @@ func (payload *edgeJobUpdatePayload) Validate(r *http.Request) error {
}
func (handler *Handler) edgeJobUpdate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
settings, err := handler.DataStore.Settings().Settings()
if err != nil {
return &httperror.HandlerError{http.StatusServiceUnavailable, "Unable to retrieve settings", err}
}
if !settings.EnableEdgeComputeFeatures {
return &httperror.HandlerError{http.StatusServiceUnavailable, "Edge compute features are disabled", portainer.ErrHostManagementFeaturesDisabled}
}
edgeJobID, err := request.RetrieveNumericRouteVariableValue(r, "id")
if err != nil {
return &httperror.HandlerError{http.StatusBadRequest, "Invalid Edge job identifier route variable", err}
@ -49,7 +41,7 @@ func (handler *Handler) edgeJobUpdate(w http.ResponseWriter, r *http.Request) *h
}
edgeJob, err := handler.DataStore.EdgeJob().EdgeJob(portainer.EdgeJobID(edgeJobID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}

View File

@ -82,13 +82,13 @@ type swarmStackFromFileContentPayload struct {
func (payload *swarmStackFromFileContentPayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.Name) {
return portainer.Error("Invalid stack name")
return errors.New("Invalid stack name")
}
if govalidator.IsNull(payload.StackFileContent) {
return portainer.Error("Invalid stack file content")
return errors.New("Invalid stack file content")
}
if payload.EdgeGroups == nil || len(payload.EdgeGroups) == 0 {
return portainer.Error("Edge Groups are mandatory for an Edge stack")
return errors.New("Edge Groups are mandatory for an Edge stack")
}
return nil
}
@ -144,19 +144,19 @@ type swarmStackFromGitRepositoryPayload struct {
func (payload *swarmStackFromGitRepositoryPayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.Name) {
return portainer.Error("Invalid stack name")
return errors.New("Invalid stack name")
}
if govalidator.IsNull(payload.RepositoryURL) || !govalidator.IsURL(payload.RepositoryURL) {
return portainer.Error("Invalid repository URL. Must correspond to a valid URL format")
return errors.New("Invalid repository URL. Must correspond to a valid URL format")
}
if payload.RepositoryAuthentication && (govalidator.IsNull(payload.RepositoryUsername) || govalidator.IsNull(payload.RepositoryPassword)) {
return portainer.Error("Invalid repository credentials. Username and password must be specified when authentication is enabled")
return errors.New("Invalid repository credentials. Username and password must be specified when authentication is enabled")
}
if govalidator.IsNull(payload.ComposeFilePathInRepository) {
payload.ComposeFilePathInRepository = filesystem.ComposeFileDefaultName
}
if payload.EdgeGroups == nil || len(payload.EdgeGroups) == 0 {
return portainer.Error("Edge Groups are mandatory for an Edge stack")
return errors.New("Edge Groups are mandatory for an Edge stack")
}
return nil
}
@ -218,20 +218,20 @@ type swarmStackFromFileUploadPayload struct {
func (payload *swarmStackFromFileUploadPayload) Validate(r *http.Request) error {
name, err := request.RetrieveMultiPartFormValue(r, "Name", false)
if err != nil {
return portainer.Error("Invalid stack name")
return errors.New("Invalid stack name")
}
payload.Name = name
composeFileContent, _, err := request.RetrieveMultiPartFormFile(r, "file")
if err != nil {
return portainer.Error("Invalid Compose file. Ensure that the Compose file is uploaded correctly")
return errors.New("Invalid Compose file. Ensure that the Compose file is uploaded correctly")
}
payload.StackFileContent = composeFileContent
var edgeGroups []portainer.EdgeGroupID
err = request.RetrieveMultiPartFormJSONValue(r, "EdgeGroups", &edgeGroups, false)
if err != nil || len(edgeGroups) == 0 {
return portainer.Error("Edge Groups are mandatory for an Edge stack")
return errors.New("Edge Groups are mandatory for an Edge stack")
}
payload.EdgeGroups = edgeGroups
return nil
@ -283,7 +283,7 @@ func (handler *Handler) validateUniqueName(name string) error {
for _, stack := range edgeStacks {
if strings.EqualFold(stack.Name, name) {
return portainer.Error("Edge stack name must be unique")
return errors.New("Edge stack name must be unique")
}
}
return nil

View File

@ -7,6 +7,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/internal/edge"
)
@ -17,7 +18,7 @@ func (handler *Handler) edgeStackDelete(w http.ResponseWriter, r *http.Request)
}
edgeStack, err := handler.DataStore.EdgeStack().EdgeStack(portainer.EdgeStackID(edgeStackID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}

View File

@ -8,6 +8,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
)
type stackFileResponse struct {
@ -22,7 +23,7 @@ func (handler *Handler) edgeStackFile(w http.ResponseWriter, r *http.Request) *h
}
stack, err := handler.DataStore.EdgeStack().EdgeStack(portainer.EdgeStackID(stackID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}

View File

@ -7,6 +7,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
)
func (handler *Handler) edgeStackInspect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
@ -16,7 +17,7 @@ func (handler *Handler) edgeStackInspect(w http.ResponseWriter, r *http.Request)
}
edgeStack, err := handler.DataStore.EdgeStack().EdgeStack(portainer.EdgeStackID(edgeStackID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}

View File

@ -1,6 +1,7 @@
package edgestacks
import (
"errors"
"net/http"
"github.com/asaskevich/govalidator"
@ -8,6 +9,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
)
type updateStatusPayload struct {
@ -18,13 +20,13 @@ type updateStatusPayload struct {
func (payload *updateStatusPayload) Validate(r *http.Request) error {
if payload.Status == nil {
return portainer.Error("Invalid status")
return errors.New("Invalid status")
}
if payload.EndpointID == nil {
return portainer.Error("Invalid EndpointID")
return errors.New("Invalid EndpointID")
}
if *payload.Status == portainer.StatusError && govalidator.IsNull(payload.Error) {
return portainer.Error("Error message is mandatory when status is error")
return errors.New("Error message is mandatory when status is error")
}
return nil
}
@ -36,7 +38,7 @@ func (handler *Handler) edgeStackStatusUpdate(w http.ResponseWriter, r *http.Req
}
stack, err := handler.DataStore.EdgeStack().EdgeStack(portainer.EdgeStackID(stackID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}
@ -49,7 +51,7 @@ func (handler *Handler) edgeStackStatusUpdate(w http.ResponseWriter, r *http.Req
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(*payload.EndpointID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}

View File

@ -1,6 +1,7 @@
package edgestacks
import (
"errors"
"net/http"
"strconv"
@ -9,6 +10,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/internal/edge"
)
@ -21,10 +23,10 @@ type updateEdgeStackPayload struct {
func (payload *updateEdgeStackPayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.StackFileContent) {
return portainer.Error("Invalid stack file content")
return errors.New("Invalid stack file content")
}
if payload.EdgeGroups != nil && len(payload.EdgeGroups) == 0 {
return portainer.Error("Edge Groups are mandatory for an Edge stack")
return errors.New("Edge Groups are mandatory for an Edge stack")
}
return nil
}
@ -36,7 +38,7 @@ func (handler *Handler) edgeStackUpdate(w http.ResponseWriter, r *http.Request)
}
stack, err := handler.DataStore.EdgeStack().EdgeStack(portainer.EdgeStackID(stackID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}

View File

@ -7,7 +7,8 @@ import (
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
)
type logsPayload struct {
@ -26,7 +27,7 @@ func (handler *Handler) endpointEdgeJobsLogs(w http.ResponseWriter, r *http.Requ
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}
@ -49,7 +50,7 @@ func (handler *Handler) endpointEdgeJobsLogs(w http.ResponseWriter, r *http.Requ
}
edgeJob, err := handler.DataStore.EdgeJob().EdgeJob(portainer.EdgeJobID(edgeJobID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}

View File

@ -8,6 +8,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
)
type configResponse struct {
@ -24,7 +25,7 @@ func (handler *Handler) endpointEdgeStackInspect(w http.ResponseWriter, r *http.
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}
@ -41,7 +42,7 @@ func (handler *Handler) endpointEdgeStackInspect(w http.ResponseWriter, r *http.
}
edgeStack, err := handler.DataStore.EdgeStack().EdgeStack(portainer.EdgeStackID(edgeStackID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}

View File

@ -1,6 +1,7 @@
package endpointgroups
import (
"errors"
"net/http"
"github.com/asaskevich/govalidator"
@ -19,7 +20,7 @@ type endpointGroupCreatePayload struct {
func (payload *endpointGroupCreatePayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.Name) {
return portainer.Error("Invalid endpoint group name")
return errors.New("Invalid endpoint group name")
}
if payload.TagIDs == nil {
payload.TagIDs = []portainer.TagID{}

View File

@ -1,12 +1,14 @@
package endpointgroups
import (
"errors"
"net/http"
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
)
// DELETE request on /api/endpoint_groups/:id
@ -17,11 +19,11 @@ func (handler *Handler) endpointGroupDelete(w http.ResponseWriter, r *http.Reque
}
if endpointGroupID == 1 {
return &httperror.HandlerError{http.StatusForbidden, "Unable to remove the default 'Unassigned' group", portainer.ErrCannotRemoveDefaultGroup}
return &httperror.HandlerError{http.StatusForbidden, "Unable to remove the default 'Unassigned' group", errors.New("Cannot remove the default endpoint group")}
}
endpointGroup, err := handler.DataStore.EndpointGroup().EndpointGroup(portainer.EndpointGroupID(endpointGroupID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint group with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint group with the specified identifier inside the database", err}

View File

@ -7,6 +7,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
)
// PUT request on /api/endpoint_groups/:id/endpoints/:endpointId
@ -22,14 +23,14 @@ func (handler *Handler) endpointGroupAddEndpoint(w http.ResponseWriter, r *http.
}
endpointGroup, err := handler.DataStore.EndpointGroup().EndpointGroup(portainer.EndpointGroupID(endpointGroupID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint group with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint group with the specified identifier inside the database", err}
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}

View File

@ -7,6 +7,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
)
// DELETE request on /api/endpoint_groups/:id/endpoints/:endpointId
@ -22,14 +23,14 @@ func (handler *Handler) endpointGroupDeleteEndpoint(w http.ResponseWriter, r *ht
}
_, err = handler.DataStore.EndpointGroup().EndpointGroup(portainer.EndpointGroupID(endpointGroupID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint group with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint group with the specified identifier inside the database", err}
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}

View File

@ -7,6 +7,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
)
// GET request on /api/endpoint_groups/:id
@ -17,7 +18,7 @@ func (handler *Handler) endpointGroupInspect(w http.ResponseWriter, r *http.Requ
}
endpointGroup, err := handler.DataStore.EndpointGroup().EndpointGroup(portainer.EndpointGroupID(endpointGroupID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint group with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint group with the specified identifier inside the database", err}

View File

@ -8,6 +8,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/internal/tag"
)
@ -37,7 +38,7 @@ func (handler *Handler) endpointGroupUpdate(w http.ResponseWriter, r *http.Reque
}
endpointGroup, err := handler.DataStore.EndpointGroup().EndpointGroup(portainer.EndpointGroupID(endpointGroupID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint group with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint group with the specified identifier inside the database", err}

View File

@ -6,6 +6,7 @@ import (
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
"net/http"
)
@ -17,7 +18,7 @@ func (handler *Handler) proxyRequestsToAzureAPI(w http.ResponseWriter, r *http.R
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}

View File

@ -8,6 +8,7 @@ import (
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
"net/http"
)
@ -19,7 +20,7 @@ func (handler *Handler) proxyRequestsToDockerAPI(w http.ResponseWriter, r *http.
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}

View File

@ -8,6 +8,7 @@ import (
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
"net/http"
)
@ -19,7 +20,7 @@ func (handler *Handler) proxyRequestsToKubernetesAPI(w http.ResponseWriter, r *h
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}

View File

@ -3,11 +3,13 @@ package endpointproxy
// TODO: legacy extension management
import (
"errors"
"strconv"
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
"net/http"
)
@ -19,7 +21,7 @@ func (handler *Handler) proxyRequestsToStoridgeAPI(w http.ResponseWriter, r *htt
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}
@ -38,7 +40,7 @@ func (handler *Handler) proxyRequestsToStoridgeAPI(w http.ResponseWriter, r *htt
}
if storidgeExtension == nil {
return &httperror.HandlerError{http.StatusServiceUnavailable, "Storidge extension not supported on this endpoint", portainer.ErrEndpointExtensionNotSupported}
return &httperror.HandlerError{http.StatusServiceUnavailable, "Storidge extension not supported on this endpoint", errors.New("This extension is not supported")}
}
proxyExtensionKey := strconv.Itoa(endpointID) + "_" + strconv.Itoa(int(portainer.StoridgeEndpointExtension)) + "_" + storidgeExtension.URL

View File

@ -39,13 +39,13 @@ type endpointCreatePayload struct {
func (payload *endpointCreatePayload) Validate(r *http.Request) error {
name, err := request.RetrieveMultiPartFormValue(r, "Name", false)
if err != nil {
return portainer.Error("Invalid endpoint name")
return errors.New("Invalid endpoint name")
}
payload.Name = name
endpointType, err := request.RetrieveNumericMultiPartFormValue(r, "EndpointType", false)
if err != nil || endpointType == 0 {
return portainer.Error("Invalid endpoint type value. Value must be one of: 1 (Docker environment), 2 (Agent environment), 3 (Azure environment) or 4 (Edge Agent environment)")
return errors.New("Invalid endpoint type value. Value must be one of: 1 (Docker environment), 2 (Agent environment), 3 (Azure environment) or 4 (Edge Agent environment)")
}
payload.EndpointType = endpointType
@ -58,7 +58,7 @@ func (payload *endpointCreatePayload) Validate(r *http.Request) error {
var tagIDs []portainer.TagID
err = request.RetrieveMultiPartFormJSONValue(r, "TagIds", &tagIDs, true)
if err != nil {
return portainer.Error("Invalid TagIds parameter")
return errors.New("Invalid TagIds parameter")
}
payload.TagIDs = tagIDs
if payload.TagIDs == nil {
@ -77,7 +77,7 @@ func (payload *endpointCreatePayload) Validate(r *http.Request) error {
if !payload.TLSSkipVerify {
caCert, _, err := request.RetrieveMultiPartFormFile(r, "TLSCACertFile")
if err != nil {
return portainer.Error("Invalid CA certificate file. Ensure that the file is uploaded correctly")
return errors.New("Invalid CA certificate file. Ensure that the file is uploaded correctly")
}
payload.TLSCACertFile = caCert
}
@ -85,13 +85,13 @@ func (payload *endpointCreatePayload) Validate(r *http.Request) error {
if !payload.TLSSkipClientVerify {
cert, _, err := request.RetrieveMultiPartFormFile(r, "TLSCertFile")
if err != nil {
return portainer.Error("Invalid certificate file. Ensure that the file is uploaded correctly")
return errors.New("Invalid certificate file. Ensure that the file is uploaded correctly")
}
payload.TLSCertFile = cert
key, _, err := request.RetrieveMultiPartFormFile(r, "TLSKeyFile")
if err != nil {
return portainer.Error("Invalid key file. Ensure that the file is uploaded correctly")
return errors.New("Invalid key file. Ensure that the file is uploaded correctly")
}
payload.TLSKeyFile = key
}
@ -101,25 +101,25 @@ func (payload *endpointCreatePayload) Validate(r *http.Request) error {
case portainer.AzureEnvironment:
azureApplicationID, err := request.RetrieveMultiPartFormValue(r, "AzureApplicationID", false)
if err != nil {
return portainer.Error("Invalid Azure application ID")
return errors.New("Invalid Azure application ID")
}
payload.AzureApplicationID = azureApplicationID
azureTenantID, err := request.RetrieveMultiPartFormValue(r, "AzureTenantID", false)
if err != nil {
return portainer.Error("Invalid Azure tenant ID")
return errors.New("Invalid Azure tenant ID")
}
payload.AzureTenantID = azureTenantID
azureAuthenticationKey, err := request.RetrieveMultiPartFormValue(r, "AzureAuthenticationKey", false)
if err != nil {
return portainer.Error("Invalid Azure authentication key")
return errors.New("Invalid Azure authentication key")
}
payload.AzureAuthenticationKey = azureAuthenticationKey
default:
endpointURL, err := request.RetrieveMultiPartFormValue(r, "URL", true)
if err != nil {
return portainer.Error("Invalid endpoint URL")
return errors.New("Invalid endpoint URL")
}
payload.URL = endpointURL

View File

@ -8,6 +8,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
)
// DELETE request on /api/endpoints/:id
@ -18,7 +19,7 @@ func (handler *Handler) endpointDelete(w http.ResponseWriter, r *http.Request) *
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}

View File

@ -3,6 +3,7 @@ package endpoints
// TODO: legacy extension management
import (
"errors"
"net/http"
"github.com/asaskevich/govalidator"
@ -10,6 +11,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
)
type endpointExtensionAddPayload struct {
@ -19,10 +21,10 @@ type endpointExtensionAddPayload struct {
func (payload *endpointExtensionAddPayload) Validate(r *http.Request) error {
if payload.Type != 1 {
return portainer.Error("Invalid type value. Value must be one of: 1 (Storidge)")
return errors.New("Invalid type value. Value must be one of: 1 (Storidge)")
}
if payload.Type == 1 && govalidator.IsNull(payload.URL) {
return portainer.Error("Invalid extension URL")
return errors.New("Invalid extension URL")
}
return nil
}
@ -35,7 +37,7 @@ func (handler *Handler) endpointExtensionAdd(w http.ResponseWriter, r *http.Requ
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}

View File

@ -9,6 +9,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
)
// DELETE request on /api/endpoints/:id/extensions/:extensionType
@ -19,7 +20,7 @@ func (handler *Handler) endpointExtensionRemove(w http.ResponseWriter, r *http.R
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}

View File

@ -7,6 +7,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
)
// GET request on /api/endpoints/:id
@ -17,7 +18,7 @@ func (handler *Handler) endpointInspect(w http.ResponseWriter, r *http.Request)
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}

View File

@ -7,6 +7,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/internal/snapshot"
)
@ -18,7 +19,7 @@ func (handler *Handler) endpointSnapshot(w http.ResponseWriter, r *http.Request)
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}

View File

@ -7,7 +7,8 @@ import (
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
)
type stackStatusResponse struct {
@ -40,7 +41,7 @@ func (handler *Handler) endpointStatusInspect(w http.ResponseWriter, r *http.Req
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}

View File

@ -9,6 +9,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/http/client"
"github.com/portainer/portainer/api/internal/edge"
"github.com/portainer/portainer/api/internal/tag"
@ -51,7 +52,7 @@ func (handler *Handler) endpointUpdate(w http.ResponseWriter, r *http.Request) *
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}

View File

@ -1,6 +1,7 @@
package extensions
import (
"errors"
"net/http"
"strconv"
@ -17,7 +18,7 @@ type extensionCreatePayload struct {
func (payload *extensionCreatePayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.License) {
return portainer.Error("Invalid license")
return errors.New("Invalid license")
}
return nil
@ -43,7 +44,7 @@ func (handler *Handler) extensionCreate(w http.ResponseWriter, r *http.Request)
for _, existingExtension := range extensions {
if existingExtension.ID == extensionID && existingExtension.Enabled {
return &httperror.HandlerError{http.StatusConflict, "Unable to enable extension", portainer.ErrExtensionAlreadyEnabled}
return &httperror.HandlerError{http.StatusConflict, "Unable to enable extension", errors.New("This extension is already enabled")}
}
}

View File

@ -7,6 +7,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
)
// DELETE request on /api/extensions/:id
@ -18,7 +19,7 @@ func (handler *Handler) extensionDelete(w http.ResponseWriter, r *http.Request)
extensionID := portainer.ExtensionID(extensionIdentifier)
extension, err := handler.DataStore.Extension().Extension(extensionID)
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find a extension with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a extension with the specified identifier inside the database", err}

View File

@ -3,12 +3,12 @@ package extensions
import (
"net/http"
"github.com/portainer/portainer/api/http/client"
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/http/client"
)
// GET request on /api/extensions/:id
@ -26,7 +26,7 @@ func (handler *Handler) extensionInspect(w http.ResponseWriter, r *http.Request)
}
localExtension, err := handler.DataStore.Extension().Extension(extensionID)
if err != nil && err != portainer.ErrObjectNotFound {
if err != nil && err != errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve extension information from the database", err}
}

View File

@ -1,6 +1,7 @@
package extensions
import (
"errors"
"net/http"
"github.com/asaskevich/govalidator"
@ -8,6 +9,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
)
type extensionUpdatePayload struct {
@ -16,7 +18,7 @@ type extensionUpdatePayload struct {
func (payload *extensionUpdatePayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.Version) {
return portainer.Error("Invalid extension version")
return errors.New("Invalid extension version")
}
return nil
@ -36,7 +38,7 @@ func (handler *Handler) extensionUpdate(w http.ResponseWriter, r *http.Request)
}
extension, err := handler.DataStore.Extension().Extension(extensionID)
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find a extension with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a extension with the specified identifier inside the database", err}

View File

@ -1,6 +1,7 @@
package extensions
import (
"errors"
"net/http"
"strconv"
@ -19,13 +20,13 @@ type extensionUploadPayload struct {
func (payload *extensionUploadPayload) Validate(r *http.Request) error {
license, err := request.RetrieveMultiPartFormValue(r, "License", false)
if err != nil {
return portainer.Error("Invalid license")
return errors.New("Invalid license")
}
payload.License = license
fileData, fileName, err := request.RetrieveMultiPartFormFile(r, "file")
if err != nil {
return portainer.Error("Invalid extension archive file. Ensure that the file is uploaded correctly")
return errors.New("Invalid extension archive file. Ensure that the file is uploaded correctly")
}
payload.ExtensionArchive = fileData
payload.ArchiveFileName = fileName

View File

@ -8,6 +8,8 @@ import (
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/http/errors"
)
// request on /api/registries/:id/v2
@ -18,7 +20,7 @@ func (handler *Handler) proxyRequestsToRegistryAPI(w http.ResponseWriter, r *htt
}
registry, err := handler.DataStore.Registry().Registry(portainer.RegistryID(registryID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}
@ -26,11 +28,11 @@ func (handler *Handler) proxyRequestsToRegistryAPI(w http.ResponseWriter, r *htt
err = handler.requestBouncer.RegistryAccess(r, registry)
if err != nil {
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access registry", portainer.ErrEndpointAccessDenied}
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access registry", errors.ErrEndpointAccessDenied}
}
extension, err := handler.DataStore.Extension().Extension(portainer.RegistryManagementExtension)
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Registry management extension is not enabled", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a extension with the specified identifier inside the database", err}

View File

@ -8,6 +8,8 @@ import (
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/http/errors"
)
// request on /api/registries/{id}/proxies/gitlab
@ -18,7 +20,7 @@ func (handler *Handler) proxyRequestsToGitlabAPIWithRegistry(w http.ResponseWrit
}
registry, err := handler.DataStore.Registry().Registry(portainer.RegistryID(registryID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}
@ -26,11 +28,11 @@ func (handler *Handler) proxyRequestsToGitlabAPIWithRegistry(w http.ResponseWrit
err = handler.requestBouncer.RegistryAccess(r, registry)
if err != nil {
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access registry", portainer.ErrEndpointAccessDenied}
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access registry", errors.ErrEndpointAccessDenied}
}
extension, err := handler.DataStore.Extension().Extension(portainer.RegistryManagementExtension)
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Registry management extension is not enabled", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a extension with the specified identifier inside the database", err}

View File

@ -1,6 +1,7 @@
package registries
import (
"errors"
"net/http"
"strconv"
@ -8,6 +9,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
)
type registryConfigurePayload struct {
@ -28,7 +30,7 @@ func (payload *registryConfigurePayload) Validate(r *http.Request) error {
if useAuthentication {
username, err := request.RetrieveMultiPartFormValue(r, "Username", false)
if err != nil {
return portainer.Error("Invalid username")
return errors.New("Invalid username")
}
payload.Username = username
@ -45,19 +47,19 @@ func (payload *registryConfigurePayload) Validate(r *http.Request) error {
if useTLS && !skipTLSVerify {
cert, _, err := request.RetrieveMultiPartFormFile(r, "TLSCertFile")
if err != nil {
return portainer.Error("Invalid certificate file. Ensure that the file is uploaded correctly")
return errors.New("Invalid certificate file. Ensure that the file is uploaded correctly")
}
payload.TLSCertFile = cert
key, _, err := request.RetrieveMultiPartFormFile(r, "TLSKeyFile")
if err != nil {
return portainer.Error("Invalid key file. Ensure that the file is uploaded correctly")
return errors.New("Invalid key file. Ensure that the file is uploaded correctly")
}
payload.TLSKeyFile = key
ca, _, err := request.RetrieveMultiPartFormFile(r, "TLSCACertFile")
if err != nil {
return portainer.Error("Invalid CA certificate file. Ensure that the file is uploaded correctly")
return errors.New("Invalid CA certificate file. Ensure that the file is uploaded correctly")
}
payload.TLSCACertFile = ca
}
@ -79,7 +81,7 @@ func (handler *Handler) registryConfigure(w http.ResponseWriter, r *http.Request
}
registry, err := handler.DataStore.Registry().Registry(portainer.RegistryID(registryID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}

View File

@ -1,6 +1,7 @@
package registries
import (
"errors"
"net/http"
"github.com/asaskevich/govalidator"
@ -22,16 +23,16 @@ type registryCreatePayload struct {
func (payload *registryCreatePayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.Name) {
return portainer.Error("Invalid registry name")
return errors.New("Invalid registry name")
}
if govalidator.IsNull(payload.URL) {
return portainer.Error("Invalid registry URL")
return errors.New("Invalid registry URL")
}
if payload.Authentication && (govalidator.IsNull(payload.Username) || govalidator.IsNull(payload.Password)) {
return portainer.Error("Invalid credentials. Username and password must be specified when authentication is enabled")
return errors.New("Invalid credentials. Username and password must be specified when authentication is enabled")
}
if payload.Type != portainer.QuayRegistry && payload.Type != portainer.AzureRegistry && payload.Type != portainer.CustomRegistry && payload.Type != portainer.GitlabRegistry {
return portainer.Error("Invalid registry type. Valid values are: 1 (Quay.io), 2 (Azure container registry), 3 (custom registry) or 4 (Gitlab registry)")
return errors.New("Invalid registry type. Valid values are: 1 (Quay.io), 2 (Azure container registry), 3 (custom registry) or 4 (Gitlab registry)")
}
return nil
}

View File

@ -7,6 +7,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
)
// DELETE request on /api/registries/:id
@ -17,7 +18,7 @@ func (handler *Handler) registryDelete(w http.ResponseWriter, r *http.Request) *
}
_, err = handler.DataStore.Registry().Registry(portainer.RegistryID(registryID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}

View File

@ -3,6 +3,9 @@ package registries
import (
"net/http"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/http/errors"
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
@ -17,7 +20,7 @@ func (handler *Handler) registryInspect(w http.ResponseWriter, r *http.Request)
}
registry, err := handler.DataStore.Registry().Registry(portainer.RegistryID(registryID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}
@ -25,7 +28,7 @@ func (handler *Handler) registryInspect(w http.ResponseWriter, r *http.Request)
err = handler.requestBouncer.RegistryAccess(r, registry)
if err != nil {
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access registry", portainer.ErrEndpointAccessDenied}
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access registry", errors.ErrEndpointAccessDenied}
}
hideFields(registry)

View File

@ -1,12 +1,14 @@
package registries
import (
"errors"
"net/http"
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
)
type registryUpdatePayload struct {
@ -37,7 +39,7 @@ func (handler *Handler) registryUpdate(w http.ResponseWriter, r *http.Request) *
}
registry, err := handler.DataStore.Registry().Registry(portainer.RegistryID(registryID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}
@ -54,7 +56,7 @@ func (handler *Handler) registryUpdate(w http.ResponseWriter, r *http.Request) *
}
for _, r := range registries {
if r.ID != registry.ID && hasSameURL(&r, registry) {
return &httperror.HandlerError{http.StatusConflict, "Another registry with the same URL already exists", portainer.ErrRegistryAlreadyExists}
return &httperror.HandlerError{http.StatusConflict, "Another registry with the same URL already exists", errors.New("A registry is already defined for this URL")}
}
}

View File

@ -21,6 +21,11 @@ type resourceControlCreatePayload struct {
SubResourceIDs []string
}
var (
errResourceControlAlreadyExists = errors.New("A resource control is already applied on this resource") //http/resourceControl
errInvalidResourceControlType = errors.New("Unsupported resource control type") //http/resourceControl
)
func (payload *resourceControlCreatePayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.ResourceID) {
return errors.New("invalid payload: invalid resource identifier")
@ -65,7 +70,7 @@ func (handler *Handler) resourceControlCreate(w http.ResponseWriter, r *http.Req
case "config":
resourceControlType = portainer.ConfigResourceControl
default:
return &httperror.HandlerError{http.StatusBadRequest, "Invalid type value. Value must be one of: container, service, volume, network, secret, stack or config", portainer.ErrInvalidResourceControlType}
return &httperror.HandlerError{http.StatusBadRequest, "Invalid type value. Value must be one of: container, service, volume, network, secret, stack or config", errInvalidResourceControlType}
}
rc, err := handler.DataStore.ResourceControl().ResourceControlByResourceIDAndType(payload.ResourceID, resourceControlType)
@ -73,7 +78,7 @@ func (handler *Handler) resourceControlCreate(w http.ResponseWriter, r *http.Req
return &httperror.HandlerError{http.StatusInternalServerError, "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", portainer.ErrResourceControlAlreadyExists}
return &httperror.HandlerError{http.StatusConflict, "A resource control is already associated to this resource", errResourceControlAlreadyExists}
}
var userAccesses = make([]portainer.UserResourceAccess, 0)

View File

@ -7,6 +7,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
)
// DELETE request on /api/resource_controls/:id
@ -17,7 +18,7 @@ func (handler *Handler) resourceControlDelete(w http.ResponseWriter, r *http.Req
}
_, err = handler.DataStore.ResourceControl().ResourceControl(portainer.ResourceControlID(resourceControlID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}

View File

@ -8,6 +8,8 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
httperrors "github.com/portainer/portainer/api/http/errors"
"github.com/portainer/portainer/api/http/security"
)
@ -43,7 +45,7 @@ func (handler *Handler) resourceControlUpdate(w http.ResponseWriter, r *http.Req
}
resourceControl, err := handler.DataStore.ResourceControl().ResourceControl(portainer.ResourceControlID(resourceControlID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}
@ -55,7 +57,7 @@ func (handler *Handler) resourceControlUpdate(w http.ResponseWriter, r *http.Req
}
if !security.AuthorizedResourceControlAccess(resourceControl, securityContext) {
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access the resource control", portainer.ErrResourceAccessDenied}
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access the resource control", httperrors.ErrResourceAccessDenied}
}
resourceControl.Public = payload.Public
@ -82,7 +84,7 @@ 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", portainer.ErrResourceAccessDenied}
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to update the resource control", httperrors.ErrResourceAccessDenied}
}
err = handler.DataStore.ResourceControl().UpdateResourceControl(resourceControl.ID, resourceControl)

View File

@ -1,6 +1,7 @@
package settings
import (
"errors"
"net/http"
"time"
@ -9,6 +10,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/filesystem"
)
@ -31,18 +33,18 @@ type settingsUpdatePayload struct {
func (payload *settingsUpdatePayload) Validate(r *http.Request) error {
if *payload.AuthenticationMethod != 1 && *payload.AuthenticationMethod != 2 && *payload.AuthenticationMethod != 3 {
return portainer.Error("Invalid authentication method value. Value must be one of: 1 (internal), 2 (LDAP/AD) or 3 (OAuth)")
return errors.New("Invalid authentication method value. Value must be one of: 1 (internal), 2 (LDAP/AD) or 3 (OAuth)")
}
if payload.LogoURL != nil && *payload.LogoURL != "" && !govalidator.IsURL(*payload.LogoURL) {
return portainer.Error("Invalid logo URL. Must correspond to a valid URL format")
return errors.New("Invalid logo URL. Must correspond to a valid URL format")
}
if payload.TemplatesURL != nil && *payload.TemplatesURL != "" && !govalidator.IsURL(*payload.TemplatesURL) {
return portainer.Error("Invalid external templates URL. Must correspond to a valid URL format")
return errors.New("Invalid external templates URL. Must correspond to a valid URL format")
}
if payload.UserSessionTimeout != nil {
_, err := time.ParseDuration(*payload.UserSessionTimeout)
if err != nil {
return portainer.Error("Invalid user session timeout")
return errors.New("Invalid user session timeout")
}
}
@ -169,7 +171,7 @@ func (handler *Handler) updateVolumeBrowserSetting(settings *portainer.Settings)
}
extension, err := handler.DataStore.Extension().Extension(portainer.RBACExtension)
if err != nil && err != portainer.ErrObjectNotFound {
if err != nil && err != bolterrors.ErrObjectNotFound {
return err
}

View File

@ -31,11 +31,11 @@ type composeStackFromFileContentPayload struct {
func (payload *composeStackFromFileContentPayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.Name) {
return portainer.Error("Invalid stack name")
return errors.New("Invalid stack name")
}
payload.Name = normalizeStackName(payload.Name)
if govalidator.IsNull(payload.StackFileContent) {
return portainer.Error("Invalid stack file content")
return errors.New("Invalid stack file content")
}
return nil
}
@ -54,7 +54,7 @@ func (handler *Handler) createComposeStackFromFileContent(w http.ResponseWriter,
for _, stack := range stacks {
if strings.EqualFold(stack.Name, payload.Name) {
return &httperror.HandlerError{http.StatusConflict, "A stack with this name already exists", portainer.ErrStackAlreadyExists}
return &httperror.HandlerError{http.StatusConflict, "A stack with this name already exists", errStackAlreadyExists}
}
}
@ -110,14 +110,14 @@ type composeStackFromGitRepositoryPayload struct {
func (payload *composeStackFromGitRepositoryPayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.Name) {
return portainer.Error("Invalid stack name")
return errors.New("Invalid stack name")
}
payload.Name = normalizeStackName(payload.Name)
if govalidator.IsNull(payload.RepositoryURL) || !govalidator.IsURL(payload.RepositoryURL) {
return portainer.Error("Invalid repository URL. Must correspond to a valid URL format")
return errors.New("Invalid repository URL. Must correspond to a valid URL format")
}
if payload.RepositoryAuthentication && (govalidator.IsNull(payload.RepositoryUsername) || govalidator.IsNull(payload.RepositoryPassword)) {
return portainer.Error("Invalid repository credentials. Username and password must be specified when authentication is enabled")
return errors.New("Invalid repository credentials. Username and password must be specified when authentication is enabled")
}
if govalidator.IsNull(payload.ComposeFilePathInRepository) {
payload.ComposeFilePathInRepository = filesystem.ComposeFileDefaultName
@ -139,7 +139,7 @@ func (handler *Handler) createComposeStackFromGitRepository(w http.ResponseWrite
for _, stack := range stacks {
if strings.EqualFold(stack.Name, payload.Name) {
return &httperror.HandlerError{http.StatusConflict, "A stack with this name already exists", portainer.ErrStackAlreadyExists}
return &httperror.HandlerError{http.StatusConflict, "A stack with this name already exists", errStackAlreadyExists}
}
}
@ -201,20 +201,20 @@ type composeStackFromFileUploadPayload struct {
func (payload *composeStackFromFileUploadPayload) Validate(r *http.Request) error {
name, err := request.RetrieveMultiPartFormValue(r, "Name", false)
if err != nil {
return portainer.Error("Invalid stack name")
return errors.New("Invalid stack name")
}
payload.Name = normalizeStackName(name)
composeFileContent, _, err := request.RetrieveMultiPartFormFile(r, "file")
if err != nil {
return portainer.Error("Invalid Compose file. Ensure that the Compose file is uploaded correctly")
return errors.New("Invalid Compose file. Ensure that the Compose file is uploaded correctly")
}
payload.StackFileContent = composeFileContent
var env []portainer.Pair
err = request.RetrieveMultiPartFormJSONValue(r, "Env", &env, true)
if err != nil {
return portainer.Error("Invalid Env parameter")
return errors.New("Invalid Env parameter")
}
payload.Env = env
return nil
@ -234,7 +234,7 @@ func (handler *Handler) createComposeStackFromFileUpload(w http.ResponseWriter,
for _, stack := range stacks {
if strings.EqualFold(stack.Name, payload.Name) {
return &httperror.HandlerError{http.StatusConflict, "A stack with this name already exists", portainer.ErrStackAlreadyExists}
return &httperror.HandlerError{http.StatusConflict, "A stack with this name already exists", errStackAlreadyExists}
}
}

View File

@ -1,6 +1,7 @@
package stacks
import (
"errors"
"net/http"
"github.com/asaskevich/govalidator"
@ -19,10 +20,10 @@ type kubernetesStackPayload struct {
func (payload *kubernetesStackPayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.StackFileContent) {
return portainer.Error("Invalid stack file content")
return errors.New("Invalid stack file content")
}
if govalidator.IsNull(payload.Namespace) {
return portainer.Error("Invalid namespace")
return errors.New("Invalid namespace")
}
return nil
}

View File

@ -24,13 +24,13 @@ type swarmStackFromFileContentPayload struct {
func (payload *swarmStackFromFileContentPayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.Name) {
return portainer.Error("Invalid stack name")
return errors.New("Invalid stack name")
}
if govalidator.IsNull(payload.SwarmID) {
return portainer.Error("Invalid Swarm ID")
return errors.New("Invalid Swarm ID")
}
if govalidator.IsNull(payload.StackFileContent) {
return portainer.Error("Invalid stack file content")
return errors.New("Invalid stack file content")
}
return nil
}
@ -49,7 +49,7 @@ func (handler *Handler) createSwarmStackFromFileContent(w http.ResponseWriter, r
for _, stack := range stacks {
if strings.EqualFold(stack.Name, payload.Name) {
return &httperror.HandlerError{http.StatusConflict, "A stack with this name already exists", portainer.ErrStackAlreadyExists}
return &httperror.HandlerError{http.StatusConflict, "A stack with this name already exists", errStackAlreadyExists}
}
}
@ -107,16 +107,16 @@ type swarmStackFromGitRepositoryPayload struct {
func (payload *swarmStackFromGitRepositoryPayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.Name) {
return portainer.Error("Invalid stack name")
return errors.New("Invalid stack name")
}
if govalidator.IsNull(payload.SwarmID) {
return portainer.Error("Invalid Swarm ID")
return errors.New("Invalid Swarm ID")
}
if govalidator.IsNull(payload.RepositoryURL) || !govalidator.IsURL(payload.RepositoryURL) {
return portainer.Error("Invalid repository URL. Must correspond to a valid URL format")
return errors.New("Invalid repository URL. Must correspond to a valid URL format")
}
if payload.RepositoryAuthentication && (govalidator.IsNull(payload.RepositoryUsername) || govalidator.IsNull(payload.RepositoryPassword)) {
return portainer.Error("Invalid repository credentials. Username and password must be specified when authentication is enabled")
return errors.New("Invalid repository credentials. Username and password must be specified when authentication is enabled")
}
if govalidator.IsNull(payload.ComposeFilePathInRepository) {
payload.ComposeFilePathInRepository = filesystem.ComposeFileDefaultName
@ -138,7 +138,7 @@ func (handler *Handler) createSwarmStackFromGitRepository(w http.ResponseWriter,
for _, stack := range stacks {
if strings.EqualFold(stack.Name, payload.Name) {
return &httperror.HandlerError{http.StatusConflict, "A stack with this name already exists", portainer.ErrStackAlreadyExists}
return &httperror.HandlerError{http.StatusConflict, "A stack with this name already exists", errStackAlreadyExists}
}
}
@ -202,26 +202,26 @@ type swarmStackFromFileUploadPayload struct {
func (payload *swarmStackFromFileUploadPayload) Validate(r *http.Request) error {
name, err := request.RetrieveMultiPartFormValue(r, "Name", false)
if err != nil {
return portainer.Error("Invalid stack name")
return errors.New("Invalid stack name")
}
payload.Name = name
swarmID, err := request.RetrieveMultiPartFormValue(r, "SwarmID", false)
if err != nil {
return portainer.Error("Invalid Swarm ID")
return errors.New("Invalid Swarm ID")
}
payload.SwarmID = swarmID
composeFileContent, _, err := request.RetrieveMultiPartFormFile(r, "file")
if err != nil {
return portainer.Error("Invalid Compose file. Ensure that the Compose file is uploaded correctly")
return errors.New("Invalid Compose file. Ensure that the Compose file is uploaded correctly")
}
payload.StackFileContent = composeFileContent
var env []portainer.Pair
err = request.RetrieveMultiPartFormJSONValue(r, "Env", &env, true)
if err != nil {
return portainer.Error("Invalid Env parameter")
return errors.New("Invalid Env parameter")
}
payload.Env = env
return nil
@ -241,7 +241,7 @@ func (handler *Handler) createSwarmStackFromFileUpload(w http.ResponseWriter, r
for _, stack := range stacks {
if strings.EqualFold(stack.Name, payload.Name) {
return &httperror.HandlerError{http.StatusConflict, "A stack with this name already exists", portainer.ErrStackAlreadyExists}
return &httperror.HandlerError{http.StatusConflict, "A stack with this name already exists", errStackAlreadyExists}
}
}

View File

@ -1,16 +1,23 @@
package stacks
import (
"errors"
"net/http"
"sync"
"github.com/gorilla/mux"
httperror "github.com/portainer/libhttp/error"
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/http/security"
"github.com/portainer/portainer/api/internal/authorization"
)
var (
errStackAlreadyExists = errors.New("A stack already exists with this name")
errStackNotExternal = errors.New("Not an external stack")
)
// Handler is the HTTP handler used to handle stack operations.
type Handler struct {
stackCreationMutex *sync.Mutex
@ -65,9 +72,9 @@ func (handler *Handler) userCanAccessStack(securityContext *security.RestrictedR
}
_, err := handler.DataStore.Extension().Extension(portainer.RBACExtension)
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return false, nil
} else if err != nil && err != portainer.ErrObjectNotFound {
} else if err != nil && err != bolterrors.ErrObjectNotFound {
return false, err
}

View File

@ -11,6 +11,8 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
httperrors "github.com/portainer/portainer/api/http/errors"
"github.com/portainer/portainer/api/http/security"
"github.com/portainer/portainer/api/internal/authorization"
)
@ -45,7 +47,7 @@ func (handler *Handler) stackCreate(w http.ResponseWriter, r *http.Request) *htt
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}
@ -68,7 +70,7 @@ func (handler *Handler) stackCreate(w http.ResponseWriter, r *http.Request) *htt
return handler.createComposeStack(w, r, method, endpoint, tokenData.ID)
case portainer.KubernetesStack:
if tokenData.Role != portainer.AdministratorRole {
return &httperror.HandlerError{http.StatusForbidden, "Access denied", portainer.ErrUnauthorized}
return &httperror.HandlerError{http.StatusForbidden, "Access denied", httperrors.ErrUnauthorized}
}
return handler.createKubernetesStack(w, r, endpoint)

View File

@ -1,15 +1,17 @@
package stacks
import (
"errors"
"net/http"
"strconv"
"github.com/portainer/portainer/api/http/security"
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
portainer "github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
httperrors "github.com/portainer/portainer/api/http/errors"
"github.com/portainer/portainer/api/http/security"
)
// DELETE request on /api/stacks/:id?external=<external>&endpointId=<endpointId>
@ -37,7 +39,7 @@ func (handler *Handler) stackDelete(w http.ResponseWriter, r *http.Request) *htt
}
stack, err := handler.DataStore.Stack().Stack(portainer.StackID(id))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}
@ -57,7 +59,7 @@ func (handler *Handler) stackDelete(w http.ResponseWriter, r *http.Request) *htt
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(endpointIdentifier)
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find the endpoint associated to the stack inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find the endpoint associated to the stack inside the database", err}
@ -78,7 +80,7 @@ func (handler *Handler) stackDelete(w http.ResponseWriter, r *http.Request) *htt
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to verify user authorizations to validate stack access", err}
}
if !access {
return &httperror.HandlerError{http.StatusForbidden, "Access denied to resource", portainer.ErrResourceAccessDenied}
return &httperror.HandlerError{http.StatusForbidden, "Access denied to resource", httperrors.ErrResourceAccessDenied}
}
err = handler.deleteStack(stack, endpoint)
@ -118,7 +120,7 @@ func (handler *Handler) deleteExternalStack(r *http.Request, w http.ResponseWrit
}
rbacExtension, err := handler.DataStore.Extension().Extension(portainer.RBACExtension)
if err != nil && err != portainer.ErrObjectNotFound {
if err != nil && err != bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to verify if RBAC extension is loaded", err}
}
@ -130,24 +132,24 @@ func (handler *Handler) deleteExternalStack(r *http.Request, w http.ResponseWrit
if rbacExtension != nil {
if !securityContext.IsAdmin && !endpointResourceAccess {
return &httperror.HandlerError{http.StatusUnauthorized, "Permission denied to delete the stack", portainer.ErrUnauthorized}
return &httperror.HandlerError{http.StatusUnauthorized, "Permission denied to delete the stack", httperrors.ErrUnauthorized}
}
} else {
if !securityContext.IsAdmin {
return &httperror.HandlerError{http.StatusUnauthorized, "Permission denied to delete the stack", portainer.ErrUnauthorized}
return &httperror.HandlerError{http.StatusUnauthorized, "Permission denied to delete the stack", httperrors.ErrUnauthorized}
}
}
stack, err := handler.DataStore.Stack().StackByName(stackName)
if err != nil && err != portainer.ErrObjectNotFound {
if err != nil && err != bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to check for stack existence inside the database", err}
}
if stack != nil {
return &httperror.HandlerError{http.StatusBadRequest, "A stack with this name exists inside the database. Cannot use external delete method", portainer.ErrStackNotExternal}
return &httperror.HandlerError{http.StatusBadRequest, "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 err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find the endpoint associated to the stack inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find the endpoint associated to the stack inside the database", err}

View File

@ -8,6 +8,8 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/http/errors"
"github.com/portainer/portainer/api/http/security"
)
@ -23,14 +25,14 @@ func (handler *Handler) stackFile(w http.ResponseWriter, r *http.Request) *httpe
}
stack, err := handler.DataStore.Stack().Stack(portainer.StackID(stackID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(stack.EndpointID)
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}
@ -56,7 +58,7 @@ func (handler *Handler) stackFile(w http.ResponseWriter, r *http.Request) *httpe
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to verify user authorizations to validate stack access", err}
}
if !access {
return &httperror.HandlerError{http.StatusForbidden, "Access denied to resource", portainer.ErrResourceAccessDenied}
return &httperror.HandlerError{http.StatusForbidden, "Access denied to resource", errors.ErrResourceAccessDenied}
}
stackFileContent, err := handler.FileService.GetFileContent(path.Join(stack.ProjectPath, stack.EntryPoint))

View File

@ -7,6 +7,8 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/http/errors"
"github.com/portainer/portainer/api/http/security"
)
@ -18,14 +20,14 @@ func (handler *Handler) stackInspect(w http.ResponseWriter, r *http.Request) *ht
}
stack, err := handler.DataStore.Stack().Stack(portainer.StackID(stackID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(stack.EndpointID)
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}
@ -51,7 +53,7 @@ func (handler *Handler) stackInspect(w http.ResponseWriter, r *http.Request) *ht
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to verify user authorizations to validate stack access", err}
}
if !access {
return &httperror.HandlerError{http.StatusForbidden, "Access denied to resource", portainer.ErrResourceAccessDenied}
return &httperror.HandlerError{http.StatusForbidden, "Access denied to resource", errors.ErrResourceAccessDenied}
}
if resourceControl != nil {

View File

@ -7,6 +7,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/http/security"
"github.com/portainer/portainer/api/internal/authorization"
)
@ -45,9 +46,9 @@ func (handler *Handler) stackList(w http.ResponseWriter, r *http.Request) *httpe
if !securityContext.IsAdmin {
rbacExtensionEnabled := true
_, err := handler.DataStore.Extension().Extension(portainer.RBACExtension)
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
rbacExtensionEnabled = false
} else if err != nil && err != portainer.ErrObjectNotFound {
} else if err != nil && err != errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to check if RBAC extension is enabled", err}
}

View File

@ -1,12 +1,15 @@
package stacks
import (
"errors"
"net/http"
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
httperrors "github.com/portainer/portainer/api/http/errors"
"github.com/portainer/portainer/api/http/security"
)
@ -18,7 +21,7 @@ type stackMigratePayload struct {
func (payload *stackMigratePayload) Validate(r *http.Request) error {
if payload.EndpointID == 0 {
return portainer.Error("Invalid endpoint identifier. Must be a positive number")
return errors.New("Invalid endpoint identifier. Must be a positive number")
}
return nil
}
@ -37,14 +40,14 @@ func (handler *Handler) stackMigrate(w http.ResponseWriter, r *http.Request) *ht
}
stack, err := handler.DataStore.Stack().Stack(portainer.StackID(stackID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(stack.EndpointID)
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}
@ -70,7 +73,7 @@ func (handler *Handler) stackMigrate(w http.ResponseWriter, r *http.Request) *ht
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to verify user authorizations to validate stack access", err}
}
if !access {
return &httperror.HandlerError{http.StatusForbidden, "Access denied to resource", portainer.ErrResourceAccessDenied}
return &httperror.HandlerError{http.StatusForbidden, "Access denied to resource", httperrors.ErrResourceAccessDenied}
}
// TODO: this is a work-around for stacks created with Portainer version >= 1.17.1
@ -85,7 +88,7 @@ func (handler *Handler) stackMigrate(w http.ResponseWriter, r *http.Request) *ht
}
targetEndpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(payload.EndpointID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}

View File

@ -1,16 +1,18 @@
package stacks
import (
"errors"
"net/http"
"strconv"
"github.com/portainer/portainer/api/http/security"
"github.com/asaskevich/govalidator"
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
httperrors "github.com/portainer/portainer/api/http/errors"
"github.com/portainer/portainer/api/http/security"
)
type updateComposeStackPayload struct {
@ -20,7 +22,7 @@ type updateComposeStackPayload struct {
func (payload *updateComposeStackPayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.StackFileContent) {
return portainer.Error("Invalid stack file content")
return errors.New("Invalid stack file content")
}
return nil
}
@ -33,7 +35,7 @@ type updateSwarmStackPayload struct {
func (payload *updateSwarmStackPayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.StackFileContent) {
return portainer.Error("Invalid stack file content")
return errors.New("Invalid stack file content")
}
return nil
}
@ -46,7 +48,7 @@ func (handler *Handler) stackUpdate(w http.ResponseWriter, r *http.Request) *htt
}
stack, err := handler.DataStore.Stack().Stack(portainer.StackID(stackID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}
@ -64,7 +66,7 @@ func (handler *Handler) stackUpdate(w http.ResponseWriter, r *http.Request) *htt
}
endpoint, err := handler.DataStore.Endpoint().Endpoint(stack.EndpointID)
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "Unable to find the endpoint associated to the stack inside the database", err}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find the endpoint associated to the stack inside the database", err}
@ -90,7 +92,7 @@ func (handler *Handler) stackUpdate(w http.ResponseWriter, r *http.Request) *htt
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to verify user authorizations to validate stack access", err}
}
if !access {
return &httperror.HandlerError{http.StatusForbidden, "Access denied to resource", portainer.ErrResourceAccessDenied}
return &httperror.HandlerError{http.StatusForbidden, "Access denied to resource", httperrors.ErrResourceAccessDenied}
}
updateError := handler.updateAndDeployStack(r, stack, endpoint)

View File

@ -1,6 +1,7 @@
package tags
import (
"errors"
"net/http"
"github.com/asaskevich/govalidator"
@ -16,7 +17,7 @@ type tagCreatePayload struct {
func (payload *tagCreatePayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.Name) {
return portainer.Error("Invalid tag name")
return errors.New("Invalid tag name")
}
return nil
}
@ -36,7 +37,7 @@ func (handler *Handler) tagCreate(w http.ResponseWriter, r *http.Request) *httpe
for _, tag := range tags {
if tag.Name == payload.Name {
return &httperror.HandlerError{http.StatusConflict, "This name is already associated to a tag", portainer.ErrTagAlreadyExists}
return &httperror.HandlerError{http.StatusConflict, "This name is already associated to a tag", errors.New("A tag already exists with this name")}
}
}

View File

@ -7,6 +7,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/internal/edge"
)
@ -19,7 +20,7 @@ func (handler *Handler) tagDelete(w http.ResponseWriter, r *http.Request) *httpe
tagID := portainer.TagID(id)
tag, err := handler.DataStore.Tag().Tag(tagID)
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}

View File

@ -1,12 +1,14 @@
package teammemberships
import (
"errors"
"net/http"
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
httperrors "github.com/portainer/portainer/api/http/errors"
"github.com/portainer/portainer/api/http/security"
)
@ -18,13 +20,13 @@ type teamMembershipCreatePayload struct {
func (payload *teamMembershipCreatePayload) Validate(r *http.Request) error {
if payload.UserID == 0 {
return portainer.Error("Invalid UserID")
return errors.New("Invalid UserID")
}
if payload.TeamID == 0 {
return portainer.Error("Invalid TeamID")
return errors.New("Invalid TeamID")
}
if payload.Role != 1 && payload.Role != 2 {
return portainer.Error("Invalid role value. Value must be one of: 1 (leader) or 2 (member)")
return errors.New("Invalid role value. Value must be one of: 1 (leader) or 2 (member)")
}
return nil
}
@ -43,7 +45,7 @@ func (handler *Handler) teamMembershipCreate(w http.ResponseWriter, r *http.Requ
}
if !security.AuthorizedTeamManagement(portainer.TeamID(payload.TeamID), securityContext) {
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to manage team memberships", portainer.ErrResourceAccessDenied}
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to manage team memberships", httperrors.ErrResourceAccessDenied}
}
memberships, err := handler.DataStore.TeamMembership().TeamMembershipsByUserID(portainer.UserID(payload.UserID))
@ -54,7 +56,7 @@ func (handler *Handler) teamMembershipCreate(w http.ResponseWriter, r *http.Requ
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", portainer.ErrTeamMembershipAlreadyExists}
return &httperror.HandlerError{http.StatusConflict, "Team membership already registered", errors.New("Team membership already exists for this user and team")}
}
}
}

View File

@ -7,6 +7,8 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/http/errors"
"github.com/portainer/portainer/api/http/security"
)
@ -18,7 +20,7 @@ func (handler *Handler) teamMembershipDelete(w http.ResponseWriter, r *http.Requ
}
membership, err := handler.DataStore.TeamMembership().TeamMembership(portainer.TeamMembershipID(membershipID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}
@ -30,7 +32,7 @@ func (handler *Handler) teamMembershipDelete(w http.ResponseWriter, r *http.Requ
}
if !security.AuthorizedTeamManagement(membership.TeamID, securityContext) {
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to delete the membership", portainer.ErrResourceAccessDenied}
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to delete the membership", errors.ErrResourceAccessDenied}
}
err = handler.DataStore.TeamMembership().DeleteTeamMembership(portainer.TeamMembershipID(membershipID))

View File

@ -5,7 +5,7 @@ import (
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/http/errors"
"github.com/portainer/portainer/api/http/security"
)
@ -17,7 +17,7 @@ func (handler *Handler) teamMembershipList(w http.ResponseWriter, r *http.Reques
}
if !securityContext.IsAdmin && !securityContext.IsTeamLeader {
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to list team memberships", portainer.ErrResourceAccessDenied}
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to list team memberships", errors.ErrResourceAccessDenied}
}
memberships, err := handler.DataStore.TeamMembership().TeamMemberships()

View File

@ -1,12 +1,15 @@
package teammemberships
import (
"errors"
"net/http"
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
httperrors "github.com/portainer/portainer/api/http/errors"
"github.com/portainer/portainer/api/http/security"
)
@ -18,13 +21,13 @@ type teamMembershipUpdatePayload struct {
func (payload *teamMembershipUpdatePayload) Validate(r *http.Request) error {
if payload.UserID == 0 {
return portainer.Error("Invalid UserID")
return errors.New("Invalid UserID")
}
if payload.TeamID == 0 {
return portainer.Error("Invalid TeamID")
return errors.New("Invalid TeamID")
}
if payload.Role != 1 && payload.Role != 2 {
return portainer.Error("Invalid role value. Value must be one of: 1 (leader) or 2 (member)")
return errors.New("Invalid role value. Value must be one of: 1 (leader) or 2 (member)")
}
return nil
}
@ -48,18 +51,18 @@ func (handler *Handler) teamMembershipUpdate(w http.ResponseWriter, r *http.Requ
}
if !security.AuthorizedTeamManagement(portainer.TeamID(payload.TeamID), securityContext) {
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to update the membership", portainer.ErrResourceAccessDenied}
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to update the membership", httperrors.ErrResourceAccessDenied}
}
membership, err := handler.DataStore.TeamMembership().TeamMembership(portainer.TeamMembershipID(membershipID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}
}
if securityContext.IsTeamLeader && membership.Role != portainer.MembershipRole(payload.Role) {
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to update the role of membership", portainer.ErrResourceAccessDenied}
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to update the role of membership", httperrors.ErrResourceAccessDenied}
}
membership.UserID = portainer.UserID(payload.UserID)

View File

@ -1,6 +1,7 @@
package teams
import (
"errors"
"net/http"
"github.com/asaskevich/govalidator"
@ -8,6 +9,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
)
type teamCreatePayload struct {
@ -16,7 +18,7 @@ type teamCreatePayload struct {
func (payload *teamCreatePayload) Validate(r *http.Request) error {
if govalidator.IsNull(payload.Name) {
return portainer.Error("Invalid team name")
return errors.New("Invalid team name")
}
return nil
}
@ -29,11 +31,11 @@ func (handler *Handler) teamCreate(w http.ResponseWriter, r *http.Request) *http
}
team, err := handler.DataStore.Team().TeamByName(payload.Name)
if err != nil && err != portainer.ErrObjectNotFound {
if err != nil && err != bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve teams from the database", err}
}
if team != nil {
return &httperror.HandlerError{http.StatusConflict, "A team with the same name already exists", portainer.ErrTeamAlreadyExists}
return &httperror.HandlerError{http.StatusConflict, "A team with the same name already exists", errors.New("Team already exists")}
}
team = &portainer.Team{

View File

@ -7,6 +7,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
)
// DELETE request on /api/teams/:id
@ -17,7 +18,7 @@ func (handler *Handler) teamDelete(w http.ResponseWriter, r *http.Request) *http
}
_, err = handler.DataStore.Team().Team(portainer.TeamID(teamID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}

View File

@ -7,6 +7,8 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
"github.com/portainer/portainer/api/http/errors"
"github.com/portainer/portainer/api/http/security"
)
@ -23,11 +25,11 @@ func (handler *Handler) teamInspect(w http.ResponseWriter, r *http.Request) *htt
}
if !security.AuthorizedTeamManagement(portainer.TeamID(teamID), securityContext) {
return &httperror.HandlerError{http.StatusForbidden, "Access denied to team", portainer.ErrResourceAccessDenied}
return &httperror.HandlerError{http.StatusForbidden, "Access denied to team", errors.ErrResourceAccessDenied}
}
team, err := handler.DataStore.Team().Team(portainer.TeamID(teamID))
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}

View File

@ -7,6 +7,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/http/errors"
"github.com/portainer/portainer/api/http/security"
)
@ -23,7 +24,7 @@ func (handler *Handler) teamMemberships(w http.ResponseWriter, r *http.Request)
}
if !security.AuthorizedTeamManagement(portainer.TeamID(teamID), securityContext) {
return &httperror.HandlerError{http.StatusForbidden, "Access denied to team", portainer.ErrResourceAccessDenied}
return &httperror.HandlerError{http.StatusForbidden, "Access denied to team", errors.ErrResourceAccessDenied}
}
memberships, err := handler.DataStore.TeamMembership().TeamMembershipsByTeamID(portainer.TeamID(teamID))

View File

@ -7,6 +7,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
)
type teamUpdatePayload struct {
@ -31,7 +32,7 @@ func (handler *Handler) teamUpdate(w http.ResponseWriter, r *http.Request) *http
}
team, err := handler.DataStore.Team().Team(portainer.TeamID(teamID))
if err == portainer.ErrObjectNotFound {
if err == errors.ErrObjectNotFound {
return &httperror.HandlerError{http.StatusNotFound, "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}

View File

@ -7,6 +7,7 @@ import (
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/filesystem"
)
// POST request on /api/upload/tls/{certificate:(?:ca|cert|key)}?folder=<folder>
@ -35,7 +36,7 @@ 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", portainer.ErrUndefinedTLSFileType}
return &httperror.HandlerError{http.StatusBadRequest, "Invalid certificate route value. Value must be one of: ca, cert or key", filesystem.ErrUndefinedTLSFileType}
}
_, err = handler.FileService.StoreTLSFileFromBytes(folder, fileType, file)

View File

@ -6,6 +6,7 @@ import (
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/response"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
)
// GET request on /api/users/admin/check
@ -16,7 +17,7 @@ func (handler *Handler) adminCheck(w http.ResponseWriter, r *http.Request) *http
}
if len(users) == 0 {
return &httperror.HandlerError{http.StatusNotFound, "No administrator account found inside the database", portainer.ErrObjectNotFound}
return &httperror.HandlerError{http.StatusNotFound, "No administrator account found inside the database", errors.ErrObjectNotFound}
}
return response.Empty(w)

Some files were not shown because too many files have changed in this diff Show More