mirror of
https://github.com/goharbor/harbor.git
synced 2024-10-03 07:47:54 +02:00
Merge pull request #5141 from ywk253100/180613_label_resource
Provide an API to return the resources that a label is referenced by
This commit is contained in:
commit
952bba6d6c
@ -1968,6 +1968,33 @@ paths:
|
|||||||
description: The resource does not exist.
|
description: The resource does not exist.
|
||||||
'500':
|
'500':
|
||||||
description: Unexpected internal errors.
|
description: Unexpected internal errors.
|
||||||
|
'/labels/{id}/resources':
|
||||||
|
get:
|
||||||
|
summary: Get the resources that the label is referenced by.
|
||||||
|
description: |
|
||||||
|
This endpoint let user get the resources that the label is referenced by. Only the replication policies are returned for now.
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
in: path
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
required: true
|
||||||
|
description: Label ID
|
||||||
|
tags:
|
||||||
|
- Products
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Get successfully.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/Resource'
|
||||||
|
'401':
|
||||||
|
description: User need to log in first.
|
||||||
|
'403':
|
||||||
|
description: Forbidden.
|
||||||
|
'404':
|
||||||
|
description: The resource does not exist.
|
||||||
|
'500':
|
||||||
|
description: Unexpected internal errors.
|
||||||
/replications:
|
/replications:
|
||||||
post:
|
post:
|
||||||
summary: Trigger the replication according to the specified policy.
|
summary: Trigger the replication according to the specified policy.
|
||||||
@ -3624,5 +3651,13 @@ definitions:
|
|||||||
ldap_group_dn:
|
ldap_group_dn:
|
||||||
type: string
|
type: string
|
||||||
description: The DN of the LDAP group if group type is 1 (LDAP group).
|
description: The DN of the LDAP group if group type is 1 (LDAP group).
|
||||||
|
Resource:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
replication_policies:
|
||||||
|
type: array
|
||||||
|
description: The replication policy list.
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/RepPolicy'
|
||||||
|
|
||||||
|
|
||||||
|
@ -141,6 +141,7 @@ func init() {
|
|||||||
beego.Router("/api/replications", &ReplicationAPI{})
|
beego.Router("/api/replications", &ReplicationAPI{})
|
||||||
beego.Router("/api/labels", &LabelAPI{}, "post:Post;get:List")
|
beego.Router("/api/labels", &LabelAPI{}, "post:Post;get:List")
|
||||||
beego.Router("/api/labels/:id([0-9]+", &LabelAPI{}, "get:Get;put:Put;delete:Delete")
|
beego.Router("/api/labels/:id([0-9]+", &LabelAPI{}, "get:Get;put:Put;delete:Delete")
|
||||||
|
beego.Router("/api/labels/:id([0-9]+)/resources", &LabelAPI{}, "get:ListResources")
|
||||||
beego.Router("/api/ping", &SystemInfoAPI{}, "get:Ping")
|
beego.Router("/api/ping", &SystemInfoAPI{}, "get:Ping")
|
||||||
_ = updateInitPassword(1, "Harbor12345")
|
_ = updateInitPassword(1, "Harbor12345")
|
||||||
|
|
||||||
|
@ -22,6 +22,9 @@ import (
|
|||||||
"github.com/vmware/harbor/src/common"
|
"github.com/vmware/harbor/src/common"
|
||||||
"github.com/vmware/harbor/src/common/dao"
|
"github.com/vmware/harbor/src/common/dao"
|
||||||
"github.com/vmware/harbor/src/common/models"
|
"github.com/vmware/harbor/src/common/models"
|
||||||
|
"github.com/vmware/harbor/src/replication"
|
||||||
|
"github.com/vmware/harbor/src/replication/core"
|
||||||
|
rep_models "github.com/vmware/harbor/src/replication/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
// LabelAPI handles requests for label management
|
// LabelAPI handles requests for label management
|
||||||
@ -266,3 +269,57 @@ func (l *LabelAPI) Delete() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListResources lists the resources that the label is referenced by
|
||||||
|
func (l *LabelAPI) ListResources() {
|
||||||
|
if !l.SecurityCtx.IsAuthenticated() {
|
||||||
|
l.HandleUnauthorized()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
id, err := l.GetInt64FromPath(":id")
|
||||||
|
if err != nil || id <= 0 {
|
||||||
|
l.HandleBadRequest("invalid label ID")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
label, err := dao.GetLabel(id)
|
||||||
|
if err != nil {
|
||||||
|
l.HandleInternalServerError(fmt.Sprintf("failed to get label %d: %v", id, err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if label == nil || label.Deleted {
|
||||||
|
l.HandleNotFound(fmt.Sprintf("label %d not found", id))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if label.Scope == common.LabelScopeGlobal && !l.SecurityCtx.IsSysAdmin() ||
|
||||||
|
label.Scope == common.LabelScopeProject && !l.SecurityCtx.HasAllPerm(label.ProjectID) {
|
||||||
|
l.HandleForbidden(l.SecurityCtx.GetUsername())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := core.GlobalController.GetPolicies(rep_models.QueryParameter{})
|
||||||
|
if err != nil {
|
||||||
|
l.HandleInternalServerError(fmt.Sprintf("failed to get policies: %v", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
policies := []*rep_models.ReplicationPolicy{}
|
||||||
|
if result != nil {
|
||||||
|
for _, policy := range result.Policies {
|
||||||
|
for _, filter := range policy.Filters {
|
||||||
|
if filter.Kind != replication.FilterItemKindLabel {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if filter.Value.(int64) == label.ID {
|
||||||
|
policies = append(policies, policy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resources := map[string]interface{}{}
|
||||||
|
resources["replication_policies"] = policies
|
||||||
|
l.Data["json"] = resources
|
||||||
|
l.ServeJSON()
|
||||||
|
}
|
||||||
|
@ -23,7 +23,10 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/vmware/harbor/src/common"
|
"github.com/vmware/harbor/src/common"
|
||||||
|
"github.com/vmware/harbor/src/common/dao"
|
||||||
"github.com/vmware/harbor/src/common/models"
|
"github.com/vmware/harbor/src/common/models"
|
||||||
|
"github.com/vmware/harbor/src/replication"
|
||||||
|
rep_models "github.com/vmware/harbor/src/replication/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -433,3 +436,105 @@ func TestLabelAPIDelete(t *testing.T) {
|
|||||||
|
|
||||||
runCodeCheckingCases(t, cases...)
|
runCodeCheckingCases(t, cases...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestListResources(t *testing.T) {
|
||||||
|
// global level label
|
||||||
|
globalLabelID, err := dao.AddLabel(&models.Label{
|
||||||
|
Name: "globel_level_label",
|
||||||
|
Scope: common.LabelScopeGlobal,
|
||||||
|
})
|
||||||
|
require.Nil(t, err)
|
||||||
|
defer dao.DeleteLabel(globalLabelID)
|
||||||
|
|
||||||
|
// project level label
|
||||||
|
projectLabelID, err := dao.AddLabel(&models.Label{
|
||||||
|
Name: "project_level_label",
|
||||||
|
Scope: common.LabelScopeProject,
|
||||||
|
ProjectID: 1,
|
||||||
|
})
|
||||||
|
require.Nil(t, err)
|
||||||
|
defer dao.DeleteLabel(projectLabelID)
|
||||||
|
|
||||||
|
targetID, err := dao.AddRepTarget(models.RepTarget{
|
||||||
|
Name: "target_for_testing_label_resource",
|
||||||
|
URL: "https://192.168.0.1",
|
||||||
|
})
|
||||||
|
require.Nil(t, err)
|
||||||
|
defer dao.DeleteRepTarget(targetID)
|
||||||
|
|
||||||
|
// create a policy references both global and project labels
|
||||||
|
policyID, err := dao.AddRepPolicy(models.RepPolicy{
|
||||||
|
Name: "policy_for_testing_label_resource",
|
||||||
|
ProjectID: 1,
|
||||||
|
TargetID: targetID,
|
||||||
|
Trigger: fmt.Sprintf(`{"kind":"%s"}`, replication.TriggerKindManual),
|
||||||
|
Filters: fmt.Sprintf(`[{"kind":"%s","value":%d}, {"kind":"%s","value":%d}]`,
|
||||||
|
replication.FilterItemKindLabel, globalLabelID,
|
||||||
|
replication.FilterItemKindLabel, projectLabelID),
|
||||||
|
})
|
||||||
|
require.Nil(t, err)
|
||||||
|
defer dao.DeleteRepPolicy(policyID)
|
||||||
|
|
||||||
|
cases := []*codeCheckingCase{
|
||||||
|
// 401
|
||||||
|
&codeCheckingCase{
|
||||||
|
request: &testingRequest{
|
||||||
|
method: http.MethodGet,
|
||||||
|
url: fmt.Sprintf("%s/%d/resources", labelAPIBasePath, globalLabelID),
|
||||||
|
},
|
||||||
|
code: http.StatusUnauthorized,
|
||||||
|
},
|
||||||
|
// 404
|
||||||
|
&codeCheckingCase{
|
||||||
|
request: &testingRequest{
|
||||||
|
method: http.MethodGet,
|
||||||
|
url: fmt.Sprintf("%s/%d/resources", labelAPIBasePath, 10000),
|
||||||
|
credential: sysAdmin,
|
||||||
|
},
|
||||||
|
code: http.StatusNotFound,
|
||||||
|
},
|
||||||
|
// 403: global level label
|
||||||
|
&codeCheckingCase{
|
||||||
|
request: &testingRequest{
|
||||||
|
method: http.MethodGet,
|
||||||
|
url: fmt.Sprintf("%s/%d/resources", labelAPIBasePath, globalLabelID),
|
||||||
|
credential: projAdmin,
|
||||||
|
},
|
||||||
|
code: http.StatusForbidden,
|
||||||
|
},
|
||||||
|
// 403: project level label
|
||||||
|
&codeCheckingCase{
|
||||||
|
request: &testingRequest{
|
||||||
|
method: http.MethodGet,
|
||||||
|
url: fmt.Sprintf("%s/%d/resources", labelAPIBasePath, projectLabelID),
|
||||||
|
credential: projDeveloper,
|
||||||
|
},
|
||||||
|
code: http.StatusForbidden,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
runCodeCheckingCases(t, cases...)
|
||||||
|
|
||||||
|
// 200: global level label
|
||||||
|
resources := map[string][]rep_models.ReplicationPolicy{}
|
||||||
|
err = handleAndParse(&testingRequest{
|
||||||
|
method: http.MethodGet,
|
||||||
|
url: fmt.Sprintf("%s/%d/resources", labelAPIBasePath, globalLabelID),
|
||||||
|
credential: sysAdmin,
|
||||||
|
}, &resources)
|
||||||
|
require.Nil(t, err)
|
||||||
|
policies := resources["replication_policies"]
|
||||||
|
require.Equal(t, 1, len(policies))
|
||||||
|
assert.Equal(t, policyID, policies[0].ID)
|
||||||
|
|
||||||
|
// 200: project level label
|
||||||
|
resources = map[string][]rep_models.ReplicationPolicy{}
|
||||||
|
err = handleAndParse(&testingRequest{
|
||||||
|
method: http.MethodGet,
|
||||||
|
url: fmt.Sprintf("%s/%d/resources", labelAPIBasePath, projectLabelID),
|
||||||
|
credential: projAdmin,
|
||||||
|
}, &resources)
|
||||||
|
require.Nil(t, err)
|
||||||
|
policies = resources["replication_policies"]
|
||||||
|
require.Equal(t, 1, len(policies))
|
||||||
|
assert.Equal(t, policyID, policies[0].ID)
|
||||||
|
}
|
||||||
|
@ -104,6 +104,7 @@ func initRouters() {
|
|||||||
beego.Router("/api/replications", &api.ReplicationAPI{})
|
beego.Router("/api/replications", &api.ReplicationAPI{})
|
||||||
beego.Router("/api/labels", &api.LabelAPI{}, "post:Post;get:List")
|
beego.Router("/api/labels", &api.LabelAPI{}, "post:Post;get:List")
|
||||||
beego.Router("/api/labels/:id([0-9]+)", &api.LabelAPI{}, "get:Get;put:Put;delete:Delete")
|
beego.Router("/api/labels/:id([0-9]+)", &api.LabelAPI{}, "get:Get;put:Put;delete:Delete")
|
||||||
|
beego.Router("/api/labels/:id([0-9]+)/resources", &api.LabelAPI{}, "get:ListResources")
|
||||||
|
|
||||||
beego.Router("/api/systeminfo", &api.SystemInfoAPI{}, "get:GetGeneralInfo")
|
beego.Router("/api/systeminfo", &api.SystemInfoAPI{}, "get:GetGeneralInfo")
|
||||||
beego.Router("/api/systeminfo/volumes", &api.SystemInfoAPI{}, "get:GetVolumeInfo")
|
beego.Router("/api/systeminfo/volumes", &api.SystemInfoAPI{}, "get:GetVolumeInfo")
|
||||||
|
Loading…
Reference in New Issue
Block a user