mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-21 17:55:30 +01:00
deprecate resource label (#19349)
There is no api is using the DAO, remove it from the source code. Signed-off-by: wang yan <wangyan@vmware.com>
This commit is contained in:
parent
97b285168a
commit
ed370a496b
1
make/migrations/postgresql/0130_2.10.0_schema.up.sql
Normal file
1
make/migrations/postgresql/0130_2.10.0_schema.up.sql
Normal file
@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS harbor_resource_label;
|
@ -1,130 +0,0 @@
|
||||
// Copyright Project Harbor Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/pkg/label/model"
|
||||
)
|
||||
|
||||
// AddResourceLabel add a label to a resource
|
||||
func AddResourceLabel(rl *models.ResourceLabel) (int64, error) {
|
||||
now := time.Now()
|
||||
rl.CreationTime = now
|
||||
rl.UpdateTime = now
|
||||
return GetOrmer().Insert(rl)
|
||||
}
|
||||
|
||||
// GetResourceLabel specified by resource ID or name
|
||||
// Get the ResourceLabel by ResourceID if rIDOrName is int
|
||||
// Get the ResourceLabel by ResourceName if rIDOrName is string
|
||||
func GetResourceLabel(rType string, rIDOrName interface{}, labelID int64) (*models.ResourceLabel, error) {
|
||||
rl := &models.ResourceLabel{
|
||||
ResourceType: rType,
|
||||
LabelID: labelID,
|
||||
}
|
||||
|
||||
var err error
|
||||
id, ok := rIDOrName.(int64)
|
||||
if ok {
|
||||
rl.ResourceID = id
|
||||
err = GetOrmer().Read(rl, "ResourceType", "ResourceID", "LabelID")
|
||||
} else {
|
||||
rl.ResourceName = rIDOrName.(string)
|
||||
err = GetOrmer().Read(rl, "ResourceType", "ResourceName", "LabelID")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if err == orm.ErrNoRows {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return rl, nil
|
||||
}
|
||||
|
||||
// GetLabelsOfResource returns the label list of the resource
|
||||
// Get the labels by ResourceID if rIDOrName is int, or get the labels by ResourceName
|
||||
func GetLabelsOfResource(rType string, rIDOrName interface{}) ([]*model.Label, error) {
|
||||
sql := `select l.id, l.name, l.description, l.color, l.scope, l.project_id, l.creation_time, l.update_time
|
||||
from harbor_resource_label rl
|
||||
join harbor_label l on rl.label_id=l.id
|
||||
where rl.resource_type = ? and`
|
||||
if _, ok := rIDOrName.(int64); ok {
|
||||
sql += ` rl.resource_id = ?`
|
||||
} else {
|
||||
sql += ` rl.resource_name = ?`
|
||||
}
|
||||
|
||||
labels := []*model.Label{}
|
||||
_, err := GetOrmer().Raw(sql, rType, rIDOrName).QueryRows(&labels)
|
||||
return labels, err
|
||||
}
|
||||
|
||||
// DeleteResourceLabel ...
|
||||
func DeleteResourceLabel(id int64) error {
|
||||
_, err := GetOrmer().Delete(&models.ResourceLabel{
|
||||
ID: id,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteLabelsOfResource removes all labels of the resource
|
||||
func DeleteLabelsOfResource(rType string, rIDOrName interface{}) error {
|
||||
qs := GetOrmer().QueryTable(&models.ResourceLabel{}).
|
||||
Filter("ResourceType", rType)
|
||||
if _, ok := rIDOrName.(int64); ok {
|
||||
qs = qs.Filter("ResourceID", rIDOrName)
|
||||
} else {
|
||||
qs = qs.Filter("ResourceName", rIDOrName)
|
||||
}
|
||||
_, err := qs.Delete()
|
||||
return err
|
||||
}
|
||||
|
||||
// ListResourceLabels lists ResourceLabel according to the query conditions
|
||||
func ListResourceLabels(query ...*models.ResourceLabelQuery) ([]*models.ResourceLabel, error) {
|
||||
qs := GetOrmer().QueryTable(&models.ResourceLabel{})
|
||||
if len(query) > 0 {
|
||||
q := query[0]
|
||||
if q.LabelID > 0 {
|
||||
qs = qs.Filter("LabelID", q.LabelID)
|
||||
}
|
||||
if len(q.ResourceType) > 0 {
|
||||
qs = qs.Filter("ResourceType", q.ResourceType)
|
||||
}
|
||||
if q.ResourceID > 0 {
|
||||
qs = qs.Filter("ResourceID", q.ResourceID)
|
||||
}
|
||||
if len(q.ResourceName) > 0 {
|
||||
qs = qs.Filter("ResourceName", q.ResourceName)
|
||||
}
|
||||
}
|
||||
|
||||
rls := []*models.ResourceLabel{}
|
||||
_, err := qs.All(&rls)
|
||||
return rls, err
|
||||
}
|
||||
|
||||
// DeleteResourceLabelByLabel delete the mapping relationship by label ID
|
||||
func DeleteResourceLabelByLabel(id int64) error {
|
||||
_, err := GetOrmer().QueryTable(&models.ResourceLabel{}).Filter("LabelID", id).Delete()
|
||||
return err
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
// Copyright Project Harbor Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package dao
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/goharbor/harbor/src/common"
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/lib/orm"
|
||||
"github.com/goharbor/harbor/src/pkg/label/dao"
|
||||
"github.com/goharbor/harbor/src/pkg/label/model"
|
||||
)
|
||||
|
||||
func TestMethodsOfResourceLabel(t *testing.T) {
|
||||
labelDao := dao.New()
|
||||
labelID, err := labelDao.Create(orm.Context(), &model.Label{
|
||||
Name: "test_label",
|
||||
Level: common.LabelLevelUser,
|
||||
Scope: common.LabelScopeGlobal,
|
||||
})
|
||||
require.Nil(t, err)
|
||||
defer labelDao.Delete(orm.Context(), labelID)
|
||||
|
||||
var resourceID int64 = 1
|
||||
resourceType := common.ResourceTypeRepository
|
||||
|
||||
// add
|
||||
rl := &models.ResourceLabel{
|
||||
LabelID: labelID,
|
||||
ResourceType: resourceType,
|
||||
ResourceID: resourceID,
|
||||
}
|
||||
|
||||
id, err := AddResourceLabel(rl)
|
||||
require.Nil(t, err)
|
||||
|
||||
// get
|
||||
r, err := GetResourceLabel(resourceType, resourceID, labelID)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, id, r.ID)
|
||||
|
||||
// get by resource
|
||||
labels, err := GetLabelsOfResource(resourceType, resourceID)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, 1, len(labels))
|
||||
assert.Equal(t, id, r.ID)
|
||||
|
||||
// list
|
||||
rls, err := ListResourceLabels(&models.ResourceLabelQuery{
|
||||
LabelID: labelID,
|
||||
ResourceType: resourceType,
|
||||
ResourceID: resourceID,
|
||||
})
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, 1, len(rls))
|
||||
assert.Equal(t, id, rls[0].ID)
|
||||
|
||||
// delete
|
||||
err = DeleteResourceLabel(id)
|
||||
require.Nil(t, err)
|
||||
labels, err = GetLabelsOfResource(resourceType, resourceID)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, 0, len(labels))
|
||||
|
||||
// delete by resource
|
||||
id, err = AddResourceLabel(rl)
|
||||
require.Nil(t, err)
|
||||
err = DeleteLabelsOfResource(resourceType, resourceID)
|
||||
require.Nil(t, err)
|
||||
labels, err = GetLabelsOfResource(resourceType, resourceID)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, 0, len(labels))
|
||||
|
||||
// delete by label ID
|
||||
id, err = AddResourceLabel(rl)
|
||||
require.Nil(t, err)
|
||||
err = DeleteResourceLabelByLabel(labelID)
|
||||
require.Nil(t, err)
|
||||
rls, err = ListResourceLabels(&models.ResourceLabelQuery{
|
||||
LabelID: labelID,
|
||||
})
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, 0, len(rls))
|
||||
}
|
@ -21,7 +21,6 @@ import (
|
||||
func init() {
|
||||
orm.RegisterModel(
|
||||
new(Role),
|
||||
new(ResourceLabel),
|
||||
new(OIDCUser),
|
||||
)
|
||||
}
|
||||
|
@ -1,43 +0,0 @@
|
||||
// Copyright Project Harbor Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// ResourceLabel records the relationship between resource and label
|
||||
type ResourceLabel struct {
|
||||
ID int64 `orm:"pk;auto;column(id)"`
|
||||
LabelID int64 `orm:"column(label_id)"`
|
||||
ResourceID int64 `orm:"column(resource_id)"`
|
||||
ResourceName string `orm:"column(resource_name)"`
|
||||
ResourceType string `orm:"column(resource_type)"`
|
||||
CreationTime time.Time `orm:"column(creation_time);auto_now_add"`
|
||||
UpdateTime time.Time `orm:"column(update_time);auto_now"`
|
||||
}
|
||||
|
||||
// TableName ...
|
||||
func (r *ResourceLabel) TableName() string {
|
||||
return "harbor_resource_label"
|
||||
}
|
||||
|
||||
// ResourceLabelQuery : query parameters for the mapping relationships of resource and label
|
||||
type ResourceLabelQuery struct {
|
||||
LabelID int64
|
||||
ResourceID int64
|
||||
ResourceName string
|
||||
ResourceType string
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
// Copyright Project Harbor Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/goharbor/harbor/src/pkg/label/model"
|
||||
)
|
||||
|
||||
func TestValidOfLabel(t *testing.T) {
|
||||
cases := []struct {
|
||||
label *model.Label
|
||||
hasError bool
|
||||
}{
|
||||
{
|
||||
label: &model.Label{
|
||||
Name: "",
|
||||
},
|
||||
hasError: true,
|
||||
},
|
||||
{
|
||||
label: &model.Label{
|
||||
Name: "test",
|
||||
Scope: "",
|
||||
},
|
||||
hasError: true,
|
||||
},
|
||||
{
|
||||
label: &model.Label{
|
||||
Name: "test",
|
||||
Scope: "invalid_scope",
|
||||
},
|
||||
hasError: true,
|
||||
},
|
||||
{
|
||||
label: &model.Label{
|
||||
Name: "test",
|
||||
Scope: "g",
|
||||
},
|
||||
hasError: false,
|
||||
},
|
||||
{
|
||||
label: &model.Label{
|
||||
Name: "test",
|
||||
Scope: "p",
|
||||
},
|
||||
hasError: true,
|
||||
},
|
||||
{
|
||||
label: &model.Label{
|
||||
Name: "test",
|
||||
Scope: "p",
|
||||
ProjectID: -1,
|
||||
},
|
||||
hasError: true,
|
||||
},
|
||||
{
|
||||
label: &model.Label{
|
||||
Name: "test",
|
||||
Scope: "p",
|
||||
ProjectID: 1,
|
||||
},
|
||||
hasError: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
err := c.label.Valid()
|
||||
if c.hasError {
|
||||
assert.NotNil(t, err)
|
||||
} else {
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,110 +0,0 @@
|
||||
// Copyright Project Harbor Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/core/label"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
pkg_label "github.com/goharbor/harbor/src/pkg/label"
|
||||
"github.com/goharbor/harbor/src/pkg/label/model"
|
||||
)
|
||||
|
||||
// LabelResourceAPI provides the related basic functions to handle marking labels to resources
|
||||
type LabelResourceAPI struct {
|
||||
BaseController
|
||||
labelManager label.Manager
|
||||
}
|
||||
|
||||
// Prepare resources for follow-up actions.
|
||||
func (lra *LabelResourceAPI) Prepare() {
|
||||
lra.BaseController.Prepare()
|
||||
|
||||
// Create label manager
|
||||
lra.labelManager = &label.BaseManager{
|
||||
LabelMgr: pkg_label.Mgr,
|
||||
}
|
||||
}
|
||||
|
||||
func (lra *LabelResourceAPI) getLabelsOfResource(rType string, rIDOrName interface{}) {
|
||||
labels, err := lra.labelManager.GetLabelsOfResource(rType, rIDOrName)
|
||||
if err != nil {
|
||||
lra.handleErrors(err)
|
||||
return
|
||||
}
|
||||
|
||||
lra.Data["json"] = labels
|
||||
if err := lra.ServeJSON(); err != nil {
|
||||
log.Errorf("failed to serve json, %v", err)
|
||||
lra.handleErrors(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (lra *LabelResourceAPI) markLabelToResource(rl *models.ResourceLabel) {
|
||||
labelID, err := lra.labelManager.MarkLabelToResource(rl)
|
||||
if err != nil {
|
||||
lra.handleErrors(err)
|
||||
return
|
||||
}
|
||||
|
||||
// return the ID of label and return status code 200 rather than 201 as the label is not created
|
||||
lra.Redirect(http.StatusOK, strconv.FormatInt(labelID, 10))
|
||||
}
|
||||
|
||||
func (lra *LabelResourceAPI) removeLabelFromResource(rType string, rIDOrName interface{}, labelID int64) {
|
||||
if err := lra.labelManager.RemoveLabelFromResource(rType, rIDOrName, labelID); err != nil {
|
||||
lra.handleErrors(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// eat the error of validate method of label manager
|
||||
func (lra *LabelResourceAPI) validate(labelID, projectID int64) (*model.Label, bool) {
|
||||
label, err := lra.labelManager.Validate(labelID, projectID)
|
||||
if err != nil {
|
||||
lra.handleErrors(err)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return label, true
|
||||
}
|
||||
|
||||
// eat the error of exists method of label manager
|
||||
func (lra *LabelResourceAPI) exists(labelID int64) (*model.Label, bool) {
|
||||
label, err := lra.labelManager.Exists(labelID)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return label, true
|
||||
}
|
||||
|
||||
// Handle different kinds of errors.
|
||||
func (lra *LabelResourceAPI) handleErrors(err error) {
|
||||
switch err.(type) {
|
||||
case *label.ErrLabelBadRequest:
|
||||
lra.SendBadRequestError(err)
|
||||
case *label.ErrLabelConflict:
|
||||
lra.SendConflictError(err)
|
||||
case *label.ErrLabelNotFound:
|
||||
lra.SendNotFoundError(err)
|
||||
default:
|
||||
lra.SendInternalServerError(err)
|
||||
}
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
// Copyright Project Harbor Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package label
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// ErrLabelBase contains the basic required info for building the final errors.
|
||||
type ErrLabelBase struct {
|
||||
LabelID int64
|
||||
ResourceType string
|
||||
ResourceIDOrName interface{}
|
||||
}
|
||||
|
||||
// ErrLabelNotFound defines the error of not found label on the resource
|
||||
// or the specified label is not found.
|
||||
type ErrLabelNotFound struct {
|
||||
ErrLabelBase
|
||||
}
|
||||
|
||||
// ErrLabelConflict defines the error of label conflicts on the resource.
|
||||
type ErrLabelConflict struct {
|
||||
ErrLabelBase
|
||||
}
|
||||
|
||||
// ErrLabelBadRequest defines the error of bad request to the resource.
|
||||
type ErrLabelBadRequest struct {
|
||||
Message string
|
||||
}
|
||||
|
||||
// NewErrLabelNotFound builds an error with ErrLabelNotFound type
|
||||
func NewErrLabelNotFound(labelID int64, resourceType string, resourceIDOrName interface{}) *ErrLabelNotFound {
|
||||
return &ErrLabelNotFound{
|
||||
ErrLabelBase{
|
||||
LabelID: labelID,
|
||||
ResourceType: resourceType,
|
||||
ResourceIDOrName: resourceIDOrName,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Error returns the error message of ErrLabelNotFound.
|
||||
func (nf *ErrLabelNotFound) Error() string {
|
||||
if len(nf.ResourceType) > 0 && nf.ResourceIDOrName != nil {
|
||||
return fmt.Sprintf("not found: label '%d' on %s '%v'", nf.LabelID, nf.ResourceType, nf.ResourceIDOrName)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("not found: label '%d'", nf.LabelID)
|
||||
}
|
||||
|
||||
// NewErrLabelConflict builds an error with NewErrLabelConflict type.
|
||||
func NewErrLabelConflict(labelID int64, resourceType string, resourceIDOrName interface{}) *ErrLabelConflict {
|
||||
return &ErrLabelConflict{
|
||||
ErrLabelBase{
|
||||
LabelID: labelID,
|
||||
ResourceType: resourceType,
|
||||
ResourceIDOrName: resourceIDOrName,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Error returns the error message of ErrLabelConflict.
|
||||
func (cl *ErrLabelConflict) Error() string {
|
||||
return fmt.Sprintf("conflict: %s '%v' is already marked with label '%d'", cl.ResourceType, cl.ResourceIDOrName, cl.LabelID)
|
||||
}
|
||||
|
||||
// NewErrLabelBadRequest builds an error with ErrLabelBadRequest type.
|
||||
func NewErrLabelBadRequest(message string) *ErrLabelBadRequest {
|
||||
return &ErrLabelBadRequest{
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// Error returns the error message of ErrLabelBadRequest.
|
||||
func (br *ErrLabelBadRequest) Error() string {
|
||||
return br.Message
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package label
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Test cases for kinds of error definitions.
|
||||
func TestErrorFormats(t *testing.T) {
|
||||
br := NewErrLabelBadRequest("bad requests")
|
||||
if !checkErrorFormat(br, "bad requests") {
|
||||
t.Fatalf("expect an error with ErrLabelBadRequest kind but got incorrect format '%v'", br)
|
||||
}
|
||||
|
||||
cf := NewErrLabelConflict(1, "c", "repo1/mychart:1.0.0")
|
||||
if !checkErrorFormat(cf, fmt.Sprintf("conflict: %s '%v' is already marked with label '%d'", "c", "repo1/mychart:1.0.0", 1)) {
|
||||
t.Fatalf("expect an error with ErrLabelConflict kind but got incorrect format '%v'", cf)
|
||||
}
|
||||
|
||||
nf := NewErrLabelNotFound(1, "c", "repo1/mychart:1.0.0")
|
||||
if !checkErrorFormat(nf, fmt.Sprintf("not found: label '%d' on %s '%v'", 1, "c", "repo1/mychart:1.0.0")) {
|
||||
t.Fatalf("expect an error with ErrLabelNotFound kind but got incorrect format '%v'", nf)
|
||||
}
|
||||
|
||||
nf2 := NewErrLabelNotFound(1, "", "")
|
||||
if !checkErrorFormat(nf2, fmt.Sprintf("not found: label '%d'", 1)) {
|
||||
t.Fatalf("expect an error with ErrLabelNotFound kind but got incorrect format %v", nf2)
|
||||
}
|
||||
}
|
||||
|
||||
func checkErrorFormat(err error, msg string) bool {
|
||||
return err.Error() == msg
|
||||
}
|
@ -1,162 +0,0 @@
|
||||
// Copyright Project Harbor Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package label
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/goharbor/harbor/src/common"
|
||||
"github.com/goharbor/harbor/src/common/dao"
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/lib/orm"
|
||||
"github.com/goharbor/harbor/src/pkg/label"
|
||||
"github.com/goharbor/harbor/src/pkg/label/model"
|
||||
)
|
||||
|
||||
// Manager defines the related operations for label management
|
||||
type Manager interface {
|
||||
// Mark label to the resource.
|
||||
//
|
||||
// If succeed, the relationship ID will be returned.
|
||||
// Otherwise, an non-nil error will be returned.
|
||||
MarkLabelToResource(label *models.ResourceLabel) (int64, error)
|
||||
|
||||
// Remove the label from the resource.
|
||||
// Resource type and ID(/name) should be provided to identify the relationship.
|
||||
//
|
||||
// An non-nil error will be got if meet any issues or nil error returned.
|
||||
RemoveLabelFromResource(resourceType string, resourceIDOrName interface{}, labelID int64) error
|
||||
|
||||
// Get labels for the specified resource.
|
||||
// Resource is identified by the resource type and ID(/name).
|
||||
//
|
||||
// If succeed, a label list is returned.
|
||||
// Otherwise, a non-nil error will be returned.
|
||||
GetLabelsOfResource(resourceType string, resourceIDOrName interface{}) ([]*model.Label, error)
|
||||
|
||||
// Check the existence of the specified label.
|
||||
//
|
||||
// If label existing, a non-nil label object is returned and nil error is set.
|
||||
// A non-nil error will be set if any issues met while checking or label is not found.
|
||||
Exists(labelID int64) (*model.Label, error)
|
||||
|
||||
// Validate if the scope of the input label is correct.
|
||||
// If the scope is project level, the projectID is required then.
|
||||
//
|
||||
// If everything is ok, an validated label reference will be returned.
|
||||
// Otherwise, a non-nil error is returned.
|
||||
Validate(labelID int64, projectID int64) (*model.Label, error)
|
||||
}
|
||||
|
||||
// BaseManager is the default implementation of the Manager interface.
|
||||
type BaseManager struct {
|
||||
LabelMgr label.Manager
|
||||
}
|
||||
|
||||
// MarkLabelToResource is the implementation of same method in Manager interface.
|
||||
func (bm *BaseManager) MarkLabelToResource(label *models.ResourceLabel) (int64, error) {
|
||||
if label == nil {
|
||||
return -1, errors.New("nil label object")
|
||||
}
|
||||
|
||||
// Use ID or name of resource. ID first.
|
||||
var rIDOrName interface{}
|
||||
if label.ResourceID != 0 {
|
||||
rIDOrName = label.ResourceID
|
||||
} else {
|
||||
rIDOrName = label.ResourceName
|
||||
}
|
||||
|
||||
rlabel, err := dao.GetResourceLabel(label.ResourceType, rIDOrName, label.LabelID)
|
||||
if err != nil {
|
||||
return -1, fmt.Errorf("failed to check the existence of label %d for resource %s %v: %v", label.LabelID, label.ResourceType, rIDOrName, err)
|
||||
}
|
||||
|
||||
if rlabel != nil {
|
||||
return -1, NewErrLabelConflict(label.LabelID, label.ResourceType, rIDOrName)
|
||||
}
|
||||
|
||||
if _, err := dao.AddResourceLabel(label); err != nil {
|
||||
return -1, fmt.Errorf("failed to add label %d to resource %s %v: %v", label.LabelID, label.ResourceType, rIDOrName, err)
|
||||
}
|
||||
|
||||
// return the ID of label
|
||||
return label.LabelID, nil
|
||||
}
|
||||
|
||||
// RemoveLabelFromResource is the implementation of same method in Manager interface.
|
||||
func (bm *BaseManager) RemoveLabelFromResource(resourceType string, resourceIDOrName interface{}, labelID int64) error {
|
||||
rl, err := dao.GetResourceLabel(resourceType, resourceIDOrName, labelID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check the existence of label %d for resource %s %v: %v", labelID, resourceType, resourceIDOrName, err)
|
||||
}
|
||||
|
||||
if rl == nil {
|
||||
return NewErrLabelNotFound(labelID, resourceType, resourceIDOrName)
|
||||
}
|
||||
|
||||
if err = dao.DeleteResourceLabel(rl.ID); err != nil {
|
||||
return fmt.Errorf("failed to delete resource label record %d: %v", rl.ID, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetLabelsOfResource is the implementation of same method in Manager interface.
|
||||
func (bm *BaseManager) GetLabelsOfResource(resourceType string, resourceIDOrName interface{}) ([]*model.Label, error) {
|
||||
labels, err := dao.GetLabelsOfResource(resourceType, resourceIDOrName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get labels of resource %s %v: %v", resourceType, resourceIDOrName, err)
|
||||
}
|
||||
|
||||
return labels, nil
|
||||
}
|
||||
|
||||
// Exists is the implementation of same method in Manager interface.
|
||||
func (bm *BaseManager) Exists(labelID int64) (*model.Label, error) {
|
||||
label, err := bm.LabelMgr.Get(orm.Context(), labelID)
|
||||
if err != nil {
|
||||
if errors.IsErr(err, errors.NotFoundCode) {
|
||||
return nil, NewErrLabelNotFound(labelID, "", nil)
|
||||
}
|
||||
return nil, fmt.Errorf("failed to get label %d: %v", labelID, err)
|
||||
}
|
||||
|
||||
return label, nil
|
||||
}
|
||||
|
||||
// Validate is the implementation of same method in Manager interface.
|
||||
func (bm *BaseManager) Validate(labelID int64, projectID int64) (*model.Label, error) {
|
||||
label, err := bm.LabelMgr.Get(orm.Context(), labelID)
|
||||
if err != nil {
|
||||
if errors.IsErr(err, errors.NotFoundCode) {
|
||||
return nil, NewErrLabelNotFound(labelID, "", nil)
|
||||
}
|
||||
return nil, fmt.Errorf("failed to get label %d: %v", labelID, err)
|
||||
}
|
||||
|
||||
if label.Level != common.LabelLevelUser {
|
||||
return nil, NewErrLabelBadRequest("only user level labels can be used")
|
||||
}
|
||||
|
||||
if label.Scope == common.LabelScopeProject {
|
||||
if projectID != label.ProjectID {
|
||||
return nil, NewErrLabelBadRequest("can not add labels which don't belong to the project to the resources under the project")
|
||||
}
|
||||
}
|
||||
|
||||
return label, nil
|
||||
}
|
@ -77,19 +77,3 @@ type Reference struct {
|
||||
func (r *Reference) TableName() string {
|
||||
return "label_reference"
|
||||
}
|
||||
|
||||
// ResourceLabel records the relationship between resource and label
|
||||
type ResourceLabel struct {
|
||||
ID int64 `orm:"pk;auto;column(id)"`
|
||||
LabelID int64 `orm:"column(label_id)"`
|
||||
ResourceID int64 `orm:"column(resource_id)"`
|
||||
ResourceName string `orm:"column(resource_name)"`
|
||||
ResourceType string `orm:"column(resource_type)"`
|
||||
CreationTime time.Time `orm:"column(creation_time);auto_now_add"`
|
||||
UpdateTime time.Time `orm:"column(update_time);auto_now"`
|
||||
}
|
||||
|
||||
// TableName ...
|
||||
func (r *ResourceLabel) TableName() string {
|
||||
return "harbor_resource_label"
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user