mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-23 10:45:45 +01:00
Merge pull request #3101 from ywk253100/170822_replica
Convert 500 error returned by Admiral to duplicate project error when creating duplicate project
This commit is contained in:
commit
f41d2ff436
@ -15,9 +15,13 @@
|
||||
package error
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// ErrDupProject is the error returned when creating a duplicate project
|
||||
var ErrDupProject = errors.New("duplicate project")
|
||||
|
||||
// HTTPError : if response is returned but the status code is not 200, an Error instance will be returned
|
||||
type HTTPError struct {
|
||||
StatusCode int
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
"github.com/vmware/harbor/src/common/dao"
|
||||
"github.com/vmware/harbor/src/common/models"
|
||||
"github.com/vmware/harbor/src/common/utils"
|
||||
errutil "github.com/vmware/harbor/src/common/utils/error"
|
||||
"github.com/vmware/harbor/src/common/utils/log"
|
||||
"github.com/vmware/harbor/src/ui/config"
|
||||
|
||||
@ -44,7 +45,6 @@ type ProjectAPI struct {
|
||||
const projectNameMaxLen int = 30
|
||||
const projectNameMinLen int = 2
|
||||
const restrictedNameChars = `[a-z0-9]+(?:[._-][a-z0-9]+)*`
|
||||
const dupProjectPattern = `Duplicate entry '\w+' for key 'name'`
|
||||
|
||||
// Prepare validates the URL and the user
|
||||
func (p *ProjectAPI) Prepare() {
|
||||
@ -130,8 +130,7 @@ func (p *ProjectAPI) Post() {
|
||||
AutomaticallyScanImagesOnPush: pro.AutomaticallyScanImagesOnPush,
|
||||
})
|
||||
if err != nil {
|
||||
dup, _ := regexp.MatchString(dupProjectPattern, err.Error())
|
||||
if dup {
|
||||
if err == errutil.ErrDupProject {
|
||||
log.Debugf("conflict %s", pro.Name)
|
||||
p.RenderError(http.StatusConflict, "")
|
||||
} else {
|
||||
|
@ -16,12 +16,17 @@ package db
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"github.com/vmware/harbor/src/common/dao"
|
||||
"github.com/vmware/harbor/src/common/models"
|
||||
errutil "github.com/vmware/harbor/src/common/utils/error"
|
||||
"github.com/vmware/harbor/src/common/utils/log"
|
||||
)
|
||||
|
||||
const dupProjectPattern = `Duplicate entry '\w+' for key 'name'`
|
||||
|
||||
// ProjectManager implements pm.PM interface based on database
|
||||
type ProjectManager struct{}
|
||||
|
||||
@ -105,7 +110,21 @@ func (p *ProjectManager) Create(project *models.Project) (int64, error) {
|
||||
UpdateTime: t,
|
||||
}
|
||||
|
||||
return dao.AddProject(*pro)
|
||||
id, err := dao.AddProject(*pro)
|
||||
if err != nil {
|
||||
dup, e := regexp.MatchString(dupProjectPattern, err.Error())
|
||||
if e != nil {
|
||||
log.Errorf("failed to match duplicate project pattern: %v", e)
|
||||
}
|
||||
|
||||
if dup {
|
||||
err = errutil.ErrDupProject
|
||||
}
|
||||
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return id, nil
|
||||
}
|
||||
|
||||
// Delete ...
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/vmware/harbor/src/common/dao"
|
||||
"github.com/vmware/harbor/src/common/models"
|
||||
errutil "github.com/vmware/harbor/src/common/utils/error"
|
||||
"github.com/vmware/harbor/src/common/utils/log"
|
||||
)
|
||||
|
||||
@ -166,6 +167,19 @@ func TestCreateAndDelete(t *testing.T) {
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
assert.Nil(t, pm.Delete(id))
|
||||
|
||||
// duplicate project name
|
||||
id, err = pm.Create(&models.Project{
|
||||
Name: "test",
|
||||
OwnerName: "admin",
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
defer pm.Delete(id)
|
||||
_, err = pm.Create(&models.Project{
|
||||
Name: "test",
|
||||
OwnerName: "admin",
|
||||
})
|
||||
assert.Equal(t, errutil.ErrDupProject, err)
|
||||
}
|
||||
|
||||
func TestUpdate(t *testing.T) {
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@ -31,6 +32,8 @@ import (
|
||||
"github.com/vmware/harbor/src/common/utils/log"
|
||||
)
|
||||
|
||||
const dupProjectPattern = `Project name '\w+' is already used`
|
||||
|
||||
// ProjectManager implements projectmanager.ProjecdtManager interface
|
||||
// base on project management service
|
||||
type ProjectManager struct {
|
||||
@ -366,6 +369,33 @@ func (p *ProjectManager) Create(pro *models.Project) (int64, error) {
|
||||
|
||||
b, err := p.send(http.MethodPost, "/projects", bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
// when creating a project with a duplicate name in Admiral, a 500 error
|
||||
// with a specific message will be returned for now.
|
||||
// Maybe a 409 error will be returned if Admiral team finds the way to
|
||||
// return a specific code in Xenon.
|
||||
// The following codes convert both those two errors to DupProjectErr
|
||||
httpErr, ok := err.(*er.HTTPError)
|
||||
if !ok {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if httpErr.StatusCode == http.StatusConflict {
|
||||
return 0, er.ErrDupProject
|
||||
}
|
||||
|
||||
if httpErr.StatusCode != http.StatusInternalServerError {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
match, e := regexp.MatchString(dupProjectPattern, httpErr.Detail)
|
||||
if e != nil {
|
||||
log.Errorf("failed to match duplicate project mattern: %v", e)
|
||||
}
|
||||
|
||||
if match {
|
||||
err = er.ErrDupProject
|
||||
}
|
||||
|
||||
return 0, err
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/vmware/harbor/src/common/models"
|
||||
errutil "github.com/vmware/harbor/src/common/utils/error"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -344,6 +345,12 @@ func TestCreate(t *testing.T) {
|
||||
assert.True(t, project.PreventVulnerableImagesFromRunning)
|
||||
assert.Equal(t, "medium", project.PreventVulnerableImagesFromRunningSeverity)
|
||||
assert.True(t, project.AutomaticallyScanImagesOnPush)
|
||||
|
||||
// duplicate project name
|
||||
_, err = pm.Create(&models.Project{
|
||||
Name: name,
|
||||
})
|
||||
assert.Equal(t, errutil.ErrDupProject, err)
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
|
Loading…
Reference in New Issue
Block a user