mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-30 06:03:45 +01:00
continue refactor API
Signed-off-by: wang yan <wangyan@vmware.com>
This commit is contained in:
parent
7c4fd79b5c
commit
8317100cda
@ -1,24 +1,21 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/goharbor/harbor/src/common/models"
|
|
||||||
"github.com/goharbor/harbor/src/common/rbac"
|
"github.com/goharbor/harbor/src/common/rbac"
|
||||||
"github.com/goharbor/harbor/src/common/utils/log"
|
|
||||||
"github.com/goharbor/harbor/src/pkg/immutabletag"
|
"github.com/goharbor/harbor/src/pkg/immutabletag"
|
||||||
"github.com/goharbor/harbor/src/pkg/retention/policy/rule"
|
"github.com/goharbor/harbor/src/pkg/immutabletag/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ImmutableTagRuleAPI ...
|
// ImmutableTagRuleAPI ...
|
||||||
type ImmutableTagRuleAPI struct {
|
type ImmutableTagRuleAPI struct {
|
||||||
BaseController
|
BaseController
|
||||||
manager immutabletag.Manager
|
ctr immutabletag.APIController
|
||||||
projectID int64
|
projectID int64
|
||||||
ID int64
|
ID int64
|
||||||
}
|
}
|
||||||
@ -49,7 +46,7 @@ func (itr *ImmutableTagRuleAPI) Prepare() {
|
|||||||
itr.ID = ruleID
|
itr.ID = ruleID
|
||||||
}
|
}
|
||||||
|
|
||||||
itr.manager = immutabletag.NewDefaultRuleManager()
|
itr.ctr = immutabletag.NewAPIController(immutabletag.NewDefaultRuleManager())
|
||||||
|
|
||||||
if strings.EqualFold(itr.Ctx.Request.Method, "get") {
|
if strings.EqualFold(itr.Ctx.Request.Method, "get") {
|
||||||
if !itr.requireAccess(rbac.ActionList) {
|
if !itr.requireAccess(rbac.ActionList) {
|
||||||
@ -77,7 +74,7 @@ func (itr *ImmutableTagRuleAPI) requireAccess(action rbac.Action) bool {
|
|||||||
|
|
||||||
// List list all immutable tag rules of current project
|
// List list all immutable tag rules of current project
|
||||||
func (itr *ImmutableTagRuleAPI) List() {
|
func (itr *ImmutableTagRuleAPI) List() {
|
||||||
rules, err := itr.manager.QueryImmutableRuleByProjectID(itr.projectID)
|
rules, err := itr.ctr.ListImmutableRules(itr.projectID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
itr.SendInternalServerError(err)
|
itr.SendInternalServerError(err)
|
||||||
return
|
return
|
||||||
@ -87,19 +84,14 @@ func (itr *ImmutableTagRuleAPI) List() {
|
|||||||
|
|
||||||
// Post create immutable tag rule
|
// Post create immutable tag rule
|
||||||
func (itr *ImmutableTagRuleAPI) Post() {
|
func (itr *ImmutableTagRuleAPI) Post() {
|
||||||
ir := &models.ImmutableRule{}
|
ir := &model.Metadata{}
|
||||||
if err := itr.DecodeJSONReq(ir); err != nil {
|
isValid, err := itr.DecodeJSONReqAndValidate(ir)
|
||||||
itr.SendBadRequestError(fmt.Errorf("the filter must be a valid json, failed to parse json, error %+v", err))
|
if !isValid {
|
||||||
|
itr.SendBadRequestError(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isValidSelectorJSON(ir.TagFilter) {
|
|
||||||
itr.SendBadRequestError(fmt.Errorf("the filter should be a valid json"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ir.ProjectID = itr.projectID
|
ir.ProjectID = itr.projectID
|
||||||
id, err := itr.manager.CreateImmutableRule(ir)
|
id, err := itr.ctr.CreateImmutableRule(ir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
itr.SendInternalServerError(err)
|
itr.SendInternalServerError(err)
|
||||||
return
|
return
|
||||||
@ -114,7 +106,7 @@ func (itr *ImmutableTagRuleAPI) Delete() {
|
|||||||
itr.SendBadRequestError(fmt.Errorf("invalid immutable rule id %d", itr.ID))
|
itr.SendBadRequestError(fmt.Errorf("invalid immutable rule id %d", itr.ID))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, err := itr.manager.DeleteImmutableRule(itr.ID)
|
err := itr.ctr.DeleteImmutableRule(itr.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
itr.SendInternalServerError(err)
|
itr.SendInternalServerError(err)
|
||||||
return
|
return
|
||||||
@ -123,9 +115,9 @@ func (itr *ImmutableTagRuleAPI) Delete() {
|
|||||||
|
|
||||||
// Put update an immutable tag rule
|
// Put update an immutable tag rule
|
||||||
func (itr *ImmutableTagRuleAPI) Put() {
|
func (itr *ImmutableTagRuleAPI) Put() {
|
||||||
ir := &models.ImmutableRule{}
|
ir := &model.Metadata{}
|
||||||
if err := itr.DecodeJSONReq(ir); err != nil {
|
if err := itr.DecodeJSONReq(ir); err != nil {
|
||||||
itr.SendInternalServerError(err)
|
itr.SendBadRequestError(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ir.ID = itr.ID
|
ir.ID = itr.ID
|
||||||
@ -135,32 +127,9 @@ func (itr *ImmutableTagRuleAPI) Put() {
|
|||||||
itr.SendBadRequestError(fmt.Errorf("invalid immutable rule id %d", itr.ID))
|
itr.SendBadRequestError(fmt.Errorf("invalid immutable rule id %d", itr.ID))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(ir.TagFilter) == 0 {
|
|
||||||
if _, err := itr.manager.EnableImmutableRule(itr.ID, ir.Enabled); err != nil {
|
|
||||||
itr.SendInternalServerError(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if !isValidSelectorJSON(ir.TagFilter) {
|
if err := itr.ctr.UpdateImmutableRule(itr.projectID, ir); err != nil {
|
||||||
itr.SendBadRequestError(fmt.Errorf("the filter should be a valid json"))
|
itr.SendInternalServerError(err)
|
||||||
return
|
return
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := itr.manager.UpdateImmutableRule(itr.ID, ir); err != nil {
|
|
||||||
itr.SendInternalServerError(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func isValidSelectorJSON(filter string) bool {
|
|
||||||
tagSector := &rule.Metadata{}
|
|
||||||
err := json.Unmarshal([]byte(filter), tagSector)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("The json is %v", filter)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
@ -7,24 +7,34 @@ import (
|
|||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/goharbor/harbor/src/common/models"
|
|
||||||
"github.com/goharbor/harbor/src/pkg/immutabletag"
|
"github.com/goharbor/harbor/src/pkg/immutabletag"
|
||||||
|
"github.com/goharbor/harbor/src/pkg/immutabletag/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestImmutableTagRuleAPI_List(t *testing.T) {
|
func TestImmutableTagRuleAPI_List(t *testing.T) {
|
||||||
|
|
||||||
tagFilter := `{
|
metadata := &model.Metadata{
|
||||||
"id":0,
|
ProjectID: 1,
|
||||||
"priority":0,
|
Disabled: false,
|
||||||
"disabled":false,
|
TagSelectors: []*model.Selector{
|
||||||
"action":"immutable",
|
{
|
||||||
"template":"immutable_template",
|
Kind: "doublestar",
|
||||||
"tag_selectors":[{"kind":"doublestar","decoration":"matches","pattern":"**"}],
|
Decoration: "matches",
|
||||||
"scope_selectors":{"repository":[{"kind":"doublestar","decoration":"repoMatches","pattern":"**"}]}
|
Pattern: "release-[\\d\\.]+",
|
||||||
}`
|
},
|
||||||
|
},
|
||||||
|
ScopeSelectors: map[string][]*model.Selector{
|
||||||
|
"repository": {
|
||||||
|
{
|
||||||
|
Kind: "doublestar",
|
||||||
|
Decoration: "matches",
|
||||||
|
Pattern: ".+",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
mgr := immutabletag.NewDefaultRuleManager()
|
mgr := immutabletag.NewDefaultRuleManager()
|
||||||
id, err := mgr.CreateImmutableRule(&models.ImmutableRule{ProjectID: 1, TagFilter: tagFilter})
|
id, err := mgr.CreateImmutableRule(metadata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@ -46,7 +56,7 @@ func TestImmutableTagRuleAPI_List(t *testing.T) {
|
|||||||
credential: admin,
|
credential: admin,
|
||||||
},
|
},
|
||||||
postFunc: func(responseRecorder *httptest.ResponseRecorder) error {
|
postFunc: func(responseRecorder *httptest.ResponseRecorder) error {
|
||||||
var rules []models.ImmutableRule
|
var rules []model.Metadata
|
||||||
err := json.Unmarshal([]byte(responseRecorder.Body.String()), &rules)
|
err := json.Unmarshal([]byte(responseRecorder.Body.String()), &rules)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -54,7 +64,7 @@ func TestImmutableTagRuleAPI_List(t *testing.T) {
|
|||||||
if len(rules) <= 0 {
|
if len(rules) <= 0 {
|
||||||
return fmt.Errorf("no rules found")
|
return fmt.Errorf("no rules found")
|
||||||
}
|
}
|
||||||
if rules[0].TagFilter != tagFilter {
|
if rules[0].TagSelectors[0].Kind != "doublestar" {
|
||||||
return fmt.Errorf("rule is not expected. actual: %v", responseRecorder.Body.String())
|
return fmt.Errorf("rule is not expected. actual: %v", responseRecorder.Body.String())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -86,43 +96,68 @@ func TestImmutableTagRuleAPI_List(t *testing.T) {
|
|||||||
|
|
||||||
func TestImmutableTagRuleAPI_Post(t *testing.T) {
|
func TestImmutableTagRuleAPI_Post(t *testing.T) {
|
||||||
|
|
||||||
tagFilter := `{
|
// body := `{
|
||||||
"id":0,
|
// "id":0,
|
||||||
"priority":0,
|
// "projectID":1,
|
||||||
"disabled":false,
|
// "priority":0,
|
||||||
"action":"immutable",
|
// "disabled":false,
|
||||||
"template":"immutable_template",
|
// "action":"immutable",
|
||||||
"tag_selectors":[{"kind":"doublestar","decoration":"matches","pattern":"**"}],
|
// "template":"immutable_template",
|
||||||
"scope_selectors":{"repository":[{"kind":"doublestar","decoration":"repoMatches","pattern":"**"}]}
|
// "tag_selectors":[{"kind":"doublestar","decoration":"matches","pattern":"**"}],
|
||||||
}`
|
// "scope_selectors":{"repository":[{"kind":"doublestar","decoration":"repoMatches","pattern":"**"}]}
|
||||||
body := &models.ImmutableRule{ProjectID: 1, TagFilter: tagFilter}
|
// }`
|
||||||
|
|
||||||
|
metadata := &model.Metadata{
|
||||||
|
ProjectID: 1,
|
||||||
|
Disabled: false,
|
||||||
|
Priority: 0,
|
||||||
|
Template: "immutable_template",
|
||||||
|
Action: "immutable",
|
||||||
|
TagSelectors: []*model.Selector{
|
||||||
|
{
|
||||||
|
Kind: "doublestar",
|
||||||
|
Decoration: "matches",
|
||||||
|
Pattern: "release-[\\d\\.]+",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ScopeSelectors: map[string][]*model.Selector{
|
||||||
|
"repository": {
|
||||||
|
{
|
||||||
|
Kind: "doublestar",
|
||||||
|
Decoration: "matches",
|
||||||
|
Pattern: ".+",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
cases := []*codeCheckingCase{
|
cases := []*codeCheckingCase{
|
||||||
// 401
|
// 401
|
||||||
{
|
{
|
||||||
request: &testingRequest{
|
request: &testingRequest{
|
||||||
method: http.MethodPost,
|
method: http.MethodPost,
|
||||||
url: "/api/projects/1/immutabletagrules",
|
url: "/api/projects/1/immutabletagrules",
|
||||||
bodyJSON: body,
|
bodyJSON: metadata,
|
||||||
},
|
},
|
||||||
code: http.StatusUnauthorized,
|
code: http.StatusUnauthorized,
|
||||||
},
|
},
|
||||||
// 200
|
// 201
|
||||||
{
|
{
|
||||||
request: &testingRequest{
|
request: &testingRequest{
|
||||||
method: http.MethodPost,
|
method: http.MethodPost,
|
||||||
url: "/api/projects/1/immutabletagrules",
|
url: "/api/projects/1/immutabletagrules",
|
||||||
credential: admin,
|
credential: admin,
|
||||||
bodyJSON: body,
|
bodyJSON: metadata,
|
||||||
},
|
},
|
||||||
code: http.StatusCreated,
|
code: http.StatusCreated,
|
||||||
},
|
},
|
||||||
// 200
|
// 201
|
||||||
{
|
{
|
||||||
request: &testingRequest{
|
request: &testingRequest{
|
||||||
method: http.MethodPost,
|
method: http.MethodPost,
|
||||||
url: "/api/projects/1/immutabletagrules",
|
url: "/api/projects/1/immutabletagrules",
|
||||||
credential: projAdmin,
|
credential: projAdmin,
|
||||||
bodyJSON: body,
|
bodyJSON: metadata,
|
||||||
},
|
},
|
||||||
code: http.StatusCreated,
|
code: http.StatusCreated,
|
||||||
},
|
},
|
||||||
@ -132,7 +167,7 @@ func TestImmutableTagRuleAPI_Post(t *testing.T) {
|
|||||||
method: http.MethodPost,
|
method: http.MethodPost,
|
||||||
url: "/api/projects/1/immutabletagrules",
|
url: "/api/projects/1/immutabletagrules",
|
||||||
credential: projGuest,
|
credential: projGuest,
|
||||||
bodyJSON: body,
|
bodyJSON: metadata,
|
||||||
},
|
},
|
||||||
code: http.StatusForbidden,
|
code: http.StatusForbidden,
|
||||||
},
|
},
|
||||||
@ -142,40 +177,63 @@ func TestImmutableTagRuleAPI_Post(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestImmutableTagRuleAPI_Put(t *testing.T) {
|
func TestImmutableTagRuleAPI_Put(t *testing.T) {
|
||||||
tagFilter := `{
|
|
||||||
"id":0,
|
|
||||||
"priority":0,
|
|
||||||
"disabled":false,
|
|
||||||
"action":"immutable",
|
|
||||||
"template":"immutable_template",
|
|
||||||
"tag_selectors":[{"kind":"doublestar","decoration":"matches","pattern":"**"}],
|
|
||||||
"scope_selectors":{"repository":[{"kind":"doublestar","decoration":"repoMatches","pattern":"**"}]}
|
|
||||||
}`
|
|
||||||
tagFilter2 := `{
|
|
||||||
"id":0,
|
|
||||||
"priority":0,
|
|
||||||
"disabled":false,
|
|
||||||
"action":"immutable",
|
|
||||||
"template":"immutable_template",
|
|
||||||
"tag_selectors":[{"kind":"doublestar","decoration":"matches","pattern":"release-1.6.0"}],
|
|
||||||
"scope_selectors":{"repository":[{"kind":"doublestar","decoration":"repoMatches","pattern":"regids"}]}
|
|
||||||
}`
|
|
||||||
|
|
||||||
|
metadata := &model.Metadata{
|
||||||
|
ProjectID: 1,
|
||||||
|
Disabled: false,
|
||||||
|
TagSelectors: []*model.Selector{
|
||||||
|
{
|
||||||
|
Kind: "doublestar",
|
||||||
|
Decoration: "matches",
|
||||||
|
Pattern: "release-[\\d\\.]+",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ScopeSelectors: map[string][]*model.Selector{
|
||||||
|
"repository": {
|
||||||
|
{
|
||||||
|
Kind: "doublestar",
|
||||||
|
Decoration: "matches",
|
||||||
|
Pattern: ".+",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
metadata2 := &model.Metadata{
|
||||||
|
ProjectID: 1,
|
||||||
|
Disabled: false,
|
||||||
|
TagSelectors: []*model.Selector{
|
||||||
|
{
|
||||||
|
Kind: "doublestar",
|
||||||
|
Decoration: "matches",
|
||||||
|
Pattern: "latest",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ScopeSelectors: map[string][]*model.Selector{
|
||||||
|
"repository": {
|
||||||
|
{
|
||||||
|
Kind: "doublestar",
|
||||||
|
Decoration: "matches",
|
||||||
|
Pattern: ".+",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
mgr := immutabletag.NewDefaultRuleManager()
|
mgr := immutabletag.NewDefaultRuleManager()
|
||||||
id, err := mgr.CreateImmutableRule(&models.ImmutableRule{ProjectID: 1, TagFilter: tagFilter})
|
id, err := mgr.CreateImmutableRule(metadata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
defer mgr.DeleteImmutableRule(id)
|
defer mgr.DeleteImmutableRule(id)
|
||||||
|
|
||||||
url := fmt.Sprintf("/api/projects/1/immutabletagrules/%d", id)
|
url := fmt.Sprintf("/api/projects/1/immutabletagrules/%d", id)
|
||||||
body := &models.ImmutableRule{ID: id, ProjectID: 1, TagFilter: tagFilter2}
|
|
||||||
cases := []*codeCheckingCase{
|
cases := []*codeCheckingCase{
|
||||||
// 401
|
// 401
|
||||||
{
|
{
|
||||||
request: &testingRequest{
|
request: &testingRequest{
|
||||||
method: http.MethodPut,
|
method: http.MethodPut,
|
||||||
url: url,
|
url: url,
|
||||||
bodyJSON: body,
|
bodyJSON: metadata2,
|
||||||
},
|
},
|
||||||
code: http.StatusUnauthorized,
|
code: http.StatusUnauthorized,
|
||||||
},
|
},
|
||||||
@ -185,7 +243,7 @@ func TestImmutableTagRuleAPI_Put(t *testing.T) {
|
|||||||
method: http.MethodPut,
|
method: http.MethodPut,
|
||||||
url: url,
|
url: url,
|
||||||
credential: admin,
|
credential: admin,
|
||||||
bodyJSON: body,
|
bodyJSON: metadata2,
|
||||||
},
|
},
|
||||||
code: http.StatusOK,
|
code: http.StatusOK,
|
||||||
},
|
},
|
||||||
@ -195,7 +253,7 @@ func TestImmutableTagRuleAPI_Put(t *testing.T) {
|
|||||||
method: http.MethodPut,
|
method: http.MethodPut,
|
||||||
url: url,
|
url: url,
|
||||||
credential: projAdmin,
|
credential: projAdmin,
|
||||||
bodyJSON: body,
|
bodyJSON: metadata2,
|
||||||
},
|
},
|
||||||
code: http.StatusOK,
|
code: http.StatusOK,
|
||||||
},
|
},
|
||||||
@ -205,7 +263,7 @@ func TestImmutableTagRuleAPI_Put(t *testing.T) {
|
|||||||
method: http.MethodPut,
|
method: http.MethodPut,
|
||||||
url: url,
|
url: url,
|
||||||
credential: projGuest,
|
credential: projGuest,
|
||||||
bodyJSON: body,
|
bodyJSON: metadata2,
|
||||||
},
|
},
|
||||||
code: http.StatusForbidden,
|
code: http.StatusForbidden,
|
||||||
},
|
},
|
||||||
@ -214,17 +272,29 @@ func TestImmutableTagRuleAPI_Put(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestImmutableTagRuleAPI_Delete(t *testing.T) {
|
func TestImmutableTagRuleAPI_Delete(t *testing.T) {
|
||||||
tagFilter := `{
|
metadata := &model.Metadata{
|
||||||
"id":0,
|
ProjectID: 1,
|
||||||
"priority":0,
|
Disabled: false,
|
||||||
"disabled":false,
|
TagSelectors: []*model.Selector{
|
||||||
"action":"immutable",
|
{
|
||||||
"template":"immutable_template",
|
Kind: "doublestar",
|
||||||
"tag_selectors":[{"kind":"doublestar","decoration":"matches","pattern":"**"}],
|
Decoration: "matches",
|
||||||
"scope_selectors":{"repository":[{"kind":"doublestar","decoration":"repoMatches","pattern":"**"}]}
|
Pattern: "latest",
|
||||||
}`
|
},
|
||||||
|
},
|
||||||
|
ScopeSelectors: map[string][]*model.Selector{
|
||||||
|
"repository": {
|
||||||
|
{
|
||||||
|
Kind: "doublestar",
|
||||||
|
Decoration: "matches",
|
||||||
|
Pattern: ".+",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
mgr := immutabletag.NewDefaultRuleManager()
|
mgr := immutabletag.NewDefaultRuleManager()
|
||||||
id, err := mgr.CreateImmutableRule(&models.ImmutableRule{ProjectID: 1, TagFilter: tagFilter})
|
id, err := mgr.CreateImmutableRule(metadata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
70
src/pkg/immutabletag/controller.go
Normal file
70
src/pkg/immutabletag/controller.go
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package immutabletag
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goharbor/harbor/src/pkg/immutabletag/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
// APIController to handle the requests related with immutabletag
|
||||||
|
type APIController interface {
|
||||||
|
// GetImmutableRule ...
|
||||||
|
GetImmutableRule(id int64) (*model.Metadata, error)
|
||||||
|
|
||||||
|
// CreateImmutableRule ...
|
||||||
|
CreateImmutableRule(m *model.Metadata) (int64, error)
|
||||||
|
|
||||||
|
// DeleteImmutableRule ...
|
||||||
|
DeleteImmutableRule(id int64) error
|
||||||
|
|
||||||
|
// UpdateImmutableRule ...
|
||||||
|
UpdateImmutableRule(pid int64, m *model.Metadata) error
|
||||||
|
|
||||||
|
// ListImmutableRules ...
|
||||||
|
ListImmutableRules(pid int64) ([]model.Metadata, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultAPIController ...
|
||||||
|
type DefaultAPIController struct {
|
||||||
|
manager Manager
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetImmutableRule ...
|
||||||
|
func (r *DefaultAPIController) GetImmutableRule(id int64) (*model.Metadata, error) {
|
||||||
|
return r.manager.GetImmutableRule(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteImmutableRule ...
|
||||||
|
func (r *DefaultAPIController) DeleteImmutableRule(id int64) error {
|
||||||
|
_, err := r.manager.DeleteImmutableRule(id)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateImmutableRule ...
|
||||||
|
func (r *DefaultAPIController) CreateImmutableRule(m *model.Metadata) (int64, error) {
|
||||||
|
return r.manager.CreateImmutableRule(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateImmutableRule ...
|
||||||
|
func (r *DefaultAPIController) UpdateImmutableRule(pid int64, m *model.Metadata) error {
|
||||||
|
m0, err := r.manager.GetImmutableRule(m.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if m0.Disabled != m.Disabled {
|
||||||
|
_, err := r.manager.EnableImmutableRule(m.ID, m.Disabled)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = r.manager.UpdateImmutableRule(pid, m)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListImmutableRules ...
|
||||||
|
func (r *DefaultAPIController) ListImmutableRules(pid int64) ([]model.Metadata, error) {
|
||||||
|
return r.manager.QueryImmutableRuleByProjectID(pid)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAPIController ...
|
||||||
|
func NewAPIController(immutableMgr Manager) APIController {
|
||||||
|
return &DefaultAPIController{
|
||||||
|
manager: immutableMgr,
|
||||||
|
}
|
||||||
|
}
|
1
src/pkg/immutabletag/controller_test.go
Normal file
1
src/pkg/immutabletag/controller_test.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package immutabletag
|
@ -1,5 +1,13 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/astaxie/beego/orm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
orm.RegisterModel(&ImmutableRule{})
|
||||||
|
}
|
||||||
|
|
||||||
// ImmutableRule - rule which filter image tags should be immutable.
|
// ImmutableRule - rule which filter image tags should be immutable.
|
||||||
type ImmutableRule struct {
|
type ImmutableRule struct {
|
||||||
ID int64 `orm:"pk;auto;column(id)" json:"id,omitempty"`
|
ID int64 `orm:"pk;auto;column(id)" json:"id,omitempty"`
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package immutabletag
|
package immutabletag
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"github.com/goharbor/harbor/src/pkg/immutabletag/dao"
|
"github.com/goharbor/harbor/src/pkg/immutabletag/dao"
|
||||||
"github.com/goharbor/harbor/src/pkg/immutabletag/dao/model"
|
dao_model "github.com/goharbor/harbor/src/pkg/immutabletag/dao/model"
|
||||||
|
"github.com/goharbor/harbor/src/pkg/immutabletag/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -13,17 +15,17 @@ var (
|
|||||||
// Manager ...
|
// Manager ...
|
||||||
type Manager interface {
|
type Manager interface {
|
||||||
// CreateImmutableRule creates the Immutable Rule
|
// CreateImmutableRule creates the Immutable Rule
|
||||||
CreateImmutableRule(ir *model.ImmutableRule) (int64, error)
|
CreateImmutableRule(m *model.Metadata) (int64, error)
|
||||||
// UpdateImmutableRule update the immutable rules
|
// UpdateImmutableRule update the immutable rules
|
||||||
UpdateImmutableRule(projectID int64, ir *model.ImmutableRule) (int64, error)
|
UpdateImmutableRule(projectID int64, ir *model.Metadata) (int64, error)
|
||||||
// EnableImmutableRule enable/disable immutable rules
|
// EnableImmutableRule enable/disable immutable rules
|
||||||
EnableImmutableRule(id int64, enabled bool) (int64, error)
|
EnableImmutableRule(id int64, enabled bool) (int64, error)
|
||||||
// GetImmutableRule get immutable rule
|
// GetImmutableRule get immutable rule
|
||||||
GetImmutableRule(id int64) (*model.ImmutableRule, error)
|
GetImmutableRule(id int64) (*model.Metadata, error)
|
||||||
// QueryImmutableRuleByProjectID get all immutable rule by project
|
// QueryImmutableRuleByProjectID get all immutable rule by project
|
||||||
QueryImmutableRuleByProjectID(projectID int64) ([]model.ImmutableRule, error)
|
QueryImmutableRuleByProjectID(projectID int64) ([]model.Metadata, error)
|
||||||
// QueryEnabledImmutableRuleByProjectID get all enabled immutable rule by project
|
// QueryEnabledImmutableRuleByProjectID get all enabled immutable rule by project
|
||||||
QueryEnabledImmutableRuleByProjectID(projectID int64) ([]model.ImmutableRule, error)
|
QueryEnabledImmutableRuleByProjectID(projectID int64) ([]model.Metadata, error)
|
||||||
// DeleteImmutableRule delete the immutable rule
|
// DeleteImmutableRule delete the immutable rule
|
||||||
DeleteImmutableRule(id int64) (int64, error)
|
DeleteImmutableRule(id int64) (int64, error)
|
||||||
}
|
}
|
||||||
@ -32,28 +34,68 @@ type defaultRuleManager struct {
|
|||||||
dao dao.ImmutableRuleDao
|
dao dao.ImmutableRuleDao
|
||||||
}
|
}
|
||||||
|
|
||||||
func (drm *defaultRuleManager) CreateImmutableRule(ir *model.ImmutableRule) (int64, error) {
|
func (drm *defaultRuleManager) CreateImmutableRule(ir *model.Metadata) (int64, error) {
|
||||||
return drm.dao.CreateImmutableRule(ir)
|
daoRule := &dao_model.ImmutableRule{}
|
||||||
|
daoRule.Enabled = !ir.Disabled
|
||||||
|
daoRule.ProjectID = ir.ProjectID
|
||||||
|
data, _ := json.Marshal(ir)
|
||||||
|
daoRule.TagFilter = string(data)
|
||||||
|
return drm.dao.CreateImmutableRule(daoRule)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (drm *defaultRuleManager) UpdateImmutableRule(projectID int64, ir *model.ImmutableRule) (int64, error) {
|
func (drm *defaultRuleManager) UpdateImmutableRule(projectID int64, ir *model.Metadata) (int64, error) {
|
||||||
return drm.dao.UpdateImmutableRule(projectID, ir)
|
daoRule := &dao_model.ImmutableRule{}
|
||||||
|
data, _ := json.Marshal(ir)
|
||||||
|
daoRule.TagFilter = string(data)
|
||||||
|
return drm.dao.UpdateImmutableRule(projectID, daoRule)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (drm *defaultRuleManager) EnableImmutableRule(id int64, enabled bool) (int64, error) {
|
func (drm *defaultRuleManager) EnableImmutableRule(id int64, enabled bool) (int64, error) {
|
||||||
return drm.dao.ToggleImmutableRule(id, enabled)
|
return drm.dao.ToggleImmutableRule(id, enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (drm *defaultRuleManager) GetImmutableRule(id int64) (*model.ImmutableRule, error) {
|
func (drm *defaultRuleManager) GetImmutableRule(id int64) (*model.Metadata, error) {
|
||||||
return drm.dao.GetImmutableRule(id)
|
daoRule, err := drm.dao.GetImmutableRule(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rule := &model.Metadata{}
|
||||||
|
if err = json.Unmarshal([]byte(daoRule.TagFilter), rule); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return rule, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (drm *defaultRuleManager) QueryImmutableRuleByProjectID(projectID int64) ([]model.ImmutableRule, error) {
|
func (drm *defaultRuleManager) QueryImmutableRuleByProjectID(projectID int64) ([]model.Metadata, error) {
|
||||||
return drm.dao.QueryImmutableRuleByProjectID(projectID)
|
daoRules, err := drm.dao.QueryImmutableRuleByProjectID(projectID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var rules []model.Metadata
|
||||||
|
for _, daoRule := range daoRules {
|
||||||
|
rule := model.Metadata{}
|
||||||
|
if err = json.Unmarshal([]byte(daoRule.TagFilter), &rule); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rules = append(rules, rule)
|
||||||
|
}
|
||||||
|
return rules, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (drm *defaultRuleManager) QueryEnabledImmutableRuleByProjectID(projectID int64) ([]model.ImmutableRule, error) {
|
func (drm *defaultRuleManager) QueryEnabledImmutableRuleByProjectID(projectID int64) ([]model.Metadata, error) {
|
||||||
return drm.dao.QueryEnabledImmutableRuleByProjectID(projectID)
|
daoRules, err := drm.dao.QueryEnabledImmutableRuleByProjectID(projectID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var rules []model.Metadata
|
||||||
|
for _, daoRule := range daoRules {
|
||||||
|
rule := model.Metadata{}
|
||||||
|
if err = json.Unmarshal([]byte(daoRule.TagFilter), &rule); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rules = append(rules, rule)
|
||||||
|
}
|
||||||
|
return rules, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (drm *defaultRuleManager) DeleteImmutableRule(id int64) (int64, error) {
|
func (drm *defaultRuleManager) DeleteImmutableRule(id int64) (int64, error) {
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
package immutabletag
|
package immutabletag
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/goharbor/harbor/src/pkg/immutabletag/dao/model"
|
dao_model "github.com/goharbor/harbor/src/pkg/immutabletag/dao/model"
|
||||||
|
"github.com/goharbor/harbor/src/pkg/immutabletag/model"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@ -15,30 +16,30 @@ type mockImmutableDao struct {
|
|||||||
mock.Mock
|
mock.Mock
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockImmutableDao) CreateImmutableRule(ir *model.ImmutableRule) (int64, error) {
|
func (m *mockImmutableDao) CreateImmutableRule(ir *dao_model.ImmutableRule) (int64, error) {
|
||||||
args := m.Called(ir)
|
args := m.Called(ir)
|
||||||
return int64(args.Int(0)), args.Error(1)
|
return int64(args.Int(0)), args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockImmutableDao) UpdateImmutableRule(projectID int64, ir *model.ImmutableRule) (int64, error) {
|
func (m *mockImmutableDao) UpdateImmutableRule(projectID int64, ir *dao_model.ImmutableRule) (int64, error) {
|
||||||
args := m.Called(ir)
|
args := m.Called(ir)
|
||||||
return int64(0), args.Error(1)
|
return int64(0), args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockImmutableDao) QueryImmutableRuleByProjectID(projectID int64) ([]model.ImmutableRule, error) {
|
func (m *mockImmutableDao) QueryImmutableRuleByProjectID(projectID int64) ([]dao_model.ImmutableRule, error) {
|
||||||
args := m.Called()
|
args := m.Called()
|
||||||
var irs []model.ImmutableRule
|
var irs []dao_model.ImmutableRule
|
||||||
if args.Get(0) != nil {
|
if args.Get(0) != nil {
|
||||||
irs = args.Get(0).([]model.ImmutableRule)
|
irs = args.Get(0).([]dao_model.ImmutableRule)
|
||||||
}
|
}
|
||||||
return irs, args.Error(1)
|
return irs, args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockImmutableDao) QueryEnabledImmutableRuleByProjectID(projectID int64) ([]model.ImmutableRule, error) {
|
func (m *mockImmutableDao) QueryEnabledImmutableRuleByProjectID(projectID int64) ([]dao_model.ImmutableRule, error) {
|
||||||
args := m.Called()
|
args := m.Called()
|
||||||
var irs []model.ImmutableRule
|
var irs []dao_model.ImmutableRule
|
||||||
if args.Get(0) != nil {
|
if args.Get(0) != nil {
|
||||||
irs = args.Get(0).([]model.ImmutableRule)
|
irs = args.Get(0).([]dao_model.ImmutableRule)
|
||||||
}
|
}
|
||||||
return irs, args.Error(1)
|
return irs, args.Error(1)
|
||||||
}
|
}
|
||||||
@ -53,11 +54,11 @@ func (m *mockImmutableDao) ToggleImmutableRule(id int64, enabled bool) (int64, e
|
|||||||
return int64(args.Int(0)), args.Error(1)
|
return int64(args.Int(0)), args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockImmutableDao) GetImmutableRule(id int64) (*model.ImmutableRule, error) {
|
func (m *mockImmutableDao) GetImmutableRule(id int64) (*dao_model.ImmutableRule, error) {
|
||||||
args := m.Called(id)
|
args := m.Called(id)
|
||||||
var ir *model.ImmutableRule
|
var ir *dao_model.ImmutableRule
|
||||||
if args.Get(0) != nil {
|
if args.Get(0) != nil {
|
||||||
ir = args.Get(0).(*model.ImmutableRule)
|
ir = args.Get(0).(*dao_model.ImmutableRule)
|
||||||
}
|
}
|
||||||
return ir, args.Error(1)
|
return ir, args.Error(1)
|
||||||
|
|
||||||
@ -98,53 +99,75 @@ func TestManagerTestingSuite(t *testing.T) {
|
|||||||
|
|
||||||
func (m *managerTestingSuite) TestCreateImmutableRule() {
|
func (m *managerTestingSuite) TestCreateImmutableRule() {
|
||||||
m.mockImmutableDao.On("CreateImmutableRule", mock.Anything).Return(1, nil)
|
m.mockImmutableDao.On("CreateImmutableRule", mock.Anything).Return(1, nil)
|
||||||
id, err := Mgr.CreateImmutableRule(&model.ImmutableRule{})
|
id, err := Mgr.CreateImmutableRule(&model.Metadata{})
|
||||||
m.mockImmutableDao.AssertCalled(m.t, "CreateImmutableRule", mock.Anything)
|
m.mockImmutableDao.AssertCalled(m.t, "CreateImmutableRule", mock.Anything)
|
||||||
m.require.Nil(err)
|
m.require.Nil(err)
|
||||||
m.assert.Equal(int64(1), id)
|
m.assert.Equal(int64(1), id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *managerTestingSuite) TestQueryImmutableRuleByProjectID() {
|
func (m *managerTestingSuite) TestQueryImmutableRuleByProjectID() {
|
||||||
m.mockImmutableDao.On("QueryImmutableRuleByProjectID", mock.Anything).Return([]model.ImmutableRule{
|
m.mockImmutableDao.On("QueryImmutableRuleByProjectID", mock.Anything).Return([]dao_model.ImmutableRule{
|
||||||
{
|
{
|
||||||
ProjectID: int64(1),
|
ID: 1,
|
||||||
TagFilter: "project_1_tag_filter",
|
ProjectID: 1,
|
||||||
Enabled: false,
|
Enabled: true,
|
||||||
|
TagFilter: "{\"id\":1, \"projectID\":1,\"priority\":0,\"disabled\":false,\"action\":\"immutable\"," +
|
||||||
|
"\"template\":\"immutable_template\"," +
|
||||||
|
"\"tag_selectors\":[{\"kind\":\"doublestar\",\"decoration\":\"matches\",\"pattern\":\"**\"}]," +
|
||||||
|
"\"scope_selectors\":{\"repository\":[{\"kind\":\"doublestar\",\"decoration\":\"repoMatches\",\"pattern\":\"**\"}]}}",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ProjectID: int64(2),
|
ID: 2,
|
||||||
TagFilter: "project_2_tag_filter",
|
ProjectID: 1,
|
||||||
Enabled: true,
|
Enabled: false,
|
||||||
|
TagFilter: "{\"id\":2, \"projectID\":1,\"priority\":0,\"disabled\":false,\"action\":\"immutable\"," +
|
||||||
|
"\"template\":\"immutable_template\"," +
|
||||||
|
"\"tag_selectors\":[{\"kind\":\"doublestar\",\"decoration\":\"matches\",\"pattern\":\"**\"}]," +
|
||||||
|
"\"scope_selectors\":{\"repository\":[{\"kind\":\"doublestar\",\"decoration\":\"repoMatches\",\"pattern\":\"**\"}]}}",
|
||||||
}}, nil)
|
}}, nil)
|
||||||
irs, err := Mgr.QueryImmutableRuleByProjectID(int64(1))
|
irs, err := Mgr.QueryImmutableRuleByProjectID(int64(1))
|
||||||
m.mockImmutableDao.AssertCalled(m.t, "QueryImmutableRuleByProjectID", mock.Anything)
|
m.mockImmutableDao.AssertCalled(m.t, "QueryImmutableRuleByProjectID", mock.Anything)
|
||||||
m.require.Nil(err)
|
m.require.Nil(err)
|
||||||
m.assert.Equal(len(irs), 2)
|
m.assert.Equal(len(irs), 2)
|
||||||
m.assert.Equal(irs[0].TagFilter, "project_1_tag_filter")
|
m.assert.Equal(irs[1].Disabled, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *managerTestingSuite) TestQueryEnabledImmutableRuleByProjectID() {
|
func (m *managerTestingSuite) TestQueryEnabledImmutableRuleByProjectID() {
|
||||||
m.mockImmutableDao.On("QueryEnabledImmutableRuleByProjectID", mock.Anything).Return([]model.ImmutableRule{
|
m.mockImmutableDao.On("QueryEnabledImmutableRuleByProjectID", mock.Anything).Return([]dao_model.ImmutableRule{
|
||||||
{
|
{
|
||||||
ProjectID: int64(1),
|
ID: 1,
|
||||||
TagFilter: "project_1_tag_filter",
|
ProjectID: 1,
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
|
TagFilter: "{\"id\":1, \"projectID\":1,\"priority\":0,\"disabled\":false,\"action\":\"immutable\"," +
|
||||||
|
"\"template\":\"immutable_template\"," +
|
||||||
|
"\"tag_selectors\":[{\"kind\":\"doublestar\",\"decoration\":\"matches\",\"pattern\":\"**\"}]," +
|
||||||
|
"\"scope_selectors\":{\"repository\":[{\"kind\":\"doublestar\",\"decoration\":\"repoMatches\",\"pattern\":\"**\"}]}}",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ProjectID: int64(2),
|
ID: 2,
|
||||||
TagFilter: "project_2_tag_filter",
|
ProjectID: 1,
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
|
TagFilter: "{\"id\":2, \"projectID\":1,\"priority\":0,\"disabled\":false,\"action\":\"immutable\"," +
|
||||||
|
"\"template\":\"immutable_template\"," +
|
||||||
|
"\"tag_selectors\":[{\"kind\":\"doublestar\",\"decoration\":\"matches\",\"pattern\":\"**\"}]," +
|
||||||
|
"\"scope_selectors\":{\"repository\":[{\"kind\":\"doublestar\",\"decoration\":\"repoMatches\",\"pattern\":\"**\"}]}}",
|
||||||
}}, nil)
|
}}, nil)
|
||||||
irs, err := Mgr.QueryEnabledImmutableRuleByProjectID(int64(1))
|
irs, err := Mgr.QueryEnabledImmutableRuleByProjectID(int64(1))
|
||||||
m.mockImmutableDao.AssertCalled(m.t, "QueryEnabledImmutableRuleByProjectID", mock.Anything)
|
m.mockImmutableDao.AssertCalled(m.t, "QueryEnabledImmutableRuleByProjectID", mock.Anything)
|
||||||
m.require.Nil(err)
|
m.require.Nil(err)
|
||||||
m.assert.Equal(len(irs), 2)
|
m.assert.Equal(len(irs), 2)
|
||||||
m.assert.Equal(irs[0].Enabled, true)
|
m.assert.Equal(irs[0].Disabled, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *managerTestingSuite) TestGetImmutableRule() {
|
func (m *managerTestingSuite) TestGetImmutableRule() {
|
||||||
m.mockImmutableDao.On("GetImmutableRule", mock.Anything).Return(&model.ImmutableRule{
|
m.mockImmutableDao.On("GetImmutableRule", mock.Anything).Return(&dao_model.ImmutableRule{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
|
ProjectID: 1,
|
||||||
|
Enabled: true,
|
||||||
|
TagFilter: "{\"id\":1, \"projectID\":1,\"priority\":0,\"disabled\":false,\"action\":\"immutable\"," +
|
||||||
|
"\"template\":\"immutable_template\"," +
|
||||||
|
"\"tag_selectors\":[{\"kind\":\"doublestar\",\"decoration\":\"matches\",\"pattern\":\"**\"}]," +
|
||||||
|
"\"scope_selectors\":{\"repository\":[{\"kind\":\"doublestar\",\"decoration\":\"repoMatches\",\"pattern\":\"**\"}]}}",
|
||||||
}, nil)
|
}, nil)
|
||||||
ir, err := Mgr.GetImmutableRule(1)
|
ir, err := Mgr.GetImmutableRule(1)
|
||||||
m.mockImmutableDao.AssertCalled(m.t, "GetImmutableRule", mock.Anything)
|
m.mockImmutableDao.AssertCalled(m.t, "GetImmutableRule", mock.Anything)
|
||||||
@ -155,7 +178,7 @@ func (m *managerTestingSuite) TestGetImmutableRule() {
|
|||||||
|
|
||||||
func (m *managerTestingSuite) TestUpdateImmutableRule() {
|
func (m *managerTestingSuite) TestUpdateImmutableRule() {
|
||||||
m.mockImmutableDao.On("UpdateImmutableRule", mock.Anything).Return(1, nil)
|
m.mockImmutableDao.On("UpdateImmutableRule", mock.Anything).Return(1, nil)
|
||||||
id, err := Mgr.UpdateImmutableRule(int64(1), &model.ImmutableRule{})
|
id, err := Mgr.UpdateImmutableRule(int64(1), &model.Metadata{})
|
||||||
m.mockImmutableDao.AssertCalled(m.t, "UpdateImmutableRule", mock.Anything)
|
m.mockImmutableDao.AssertCalled(m.t, "UpdateImmutableRule", mock.Anything)
|
||||||
m.require.Nil(err)
|
m.require.Nil(err)
|
||||||
m.assert.Equal(int64(0), id)
|
m.assert.Equal(int64(0), id)
|
||||||
|
@ -7,7 +7,10 @@ import (
|
|||||||
// Metadata of the immutable rule
|
// Metadata of the immutable rule
|
||||||
type Metadata struct {
|
type Metadata struct {
|
||||||
// UUID of rule
|
// UUID of rule
|
||||||
ID int `json:"id"`
|
ID int64 `json:"id"`
|
||||||
|
|
||||||
|
// ProjectID of project
|
||||||
|
ProjectID int64 `json:"project_id"`
|
||||||
|
|
||||||
// Disabled rule
|
// Disabled rule
|
||||||
Disabled bool `json:"disabled"`
|
Disabled bool `json:"disabled"`
|
||||||
|
Loading…
Reference in New Issue
Block a user