mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-26 20:26:13 +01:00
Merge pull request #16865 from stonezdj/22may17_purge_audit_log_rest_api
Add REST API for purge audit log
This commit is contained in:
commit
4637af8866
@ -4174,6 +4174,170 @@ paths:
|
|||||||
$ref: '#/responses/403'
|
$ref: '#/responses/403'
|
||||||
'500':
|
'500':
|
||||||
$ref: '#/responses/500'
|
$ref: '#/responses/500'
|
||||||
|
/system/purgeaudit:
|
||||||
|
get:
|
||||||
|
summary: Get purge job results.
|
||||||
|
description: get purge job execution history.
|
||||||
|
tags:
|
||||||
|
- purge
|
||||||
|
operationId: getPurgeHistory
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/parameters/requestId'
|
||||||
|
- $ref: '#/parameters/query'
|
||||||
|
- $ref: '#/parameters/sort'
|
||||||
|
- $ref: '#/parameters/page'
|
||||||
|
- $ref: '#/parameters/pageSize'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Get purge job results successfully.
|
||||||
|
headers:
|
||||||
|
X-Total-Count:
|
||||||
|
description: The total count of history
|
||||||
|
type: integer
|
||||||
|
Link:
|
||||||
|
description: Link refers to the previous page and next page
|
||||||
|
type: string
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/ExecHistory'
|
||||||
|
'401':
|
||||||
|
$ref: '#/responses/401'
|
||||||
|
'403':
|
||||||
|
$ref: '#/responses/403'
|
||||||
|
'500':
|
||||||
|
$ref: '#/responses/500'
|
||||||
|
/system/purgeaudit/{purge_id}:
|
||||||
|
get:
|
||||||
|
summary: Get purge job status.
|
||||||
|
description: This endpoint let user get purge job status filtered by specific ID.
|
||||||
|
operationId: getPurgeJob
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/parameters/requestId'
|
||||||
|
- $ref: '#/parameters/purgeId'
|
||||||
|
tags:
|
||||||
|
- purge
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Get purge job results successfully.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/ExecHistory'
|
||||||
|
'401':
|
||||||
|
$ref: '#/responses/401'
|
||||||
|
'403':
|
||||||
|
$ref: '#/responses/403'
|
||||||
|
'404':
|
||||||
|
$ref: '#/responses/404'
|
||||||
|
'500':
|
||||||
|
$ref: '#/responses/500'
|
||||||
|
/system/purgeaudit/{purge_id}/log:
|
||||||
|
get:
|
||||||
|
summary: Get purge job log.
|
||||||
|
description: This endpoint let user get purge job logs filtered by specific ID.
|
||||||
|
operationId: getPurgeJobLog
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/parameters/requestId'
|
||||||
|
- $ref: '#/parameters/purgeId'
|
||||||
|
tags:
|
||||||
|
- purge
|
||||||
|
produces:
|
||||||
|
- text/plain
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Get successfully.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
'400':
|
||||||
|
$ref: '#/responses/400'
|
||||||
|
'401':
|
||||||
|
$ref: '#/responses/401'
|
||||||
|
'403':
|
||||||
|
$ref: '#/responses/403'
|
||||||
|
'404':
|
||||||
|
$ref: '#/responses/404'
|
||||||
|
'500':
|
||||||
|
$ref: '#/responses/500'
|
||||||
|
/system/purgeaudit/schedule:
|
||||||
|
get:
|
||||||
|
summary: Get purge's schedule.
|
||||||
|
description: This endpoint is for get schedule of purge job.
|
||||||
|
operationId: getPurgeSchedule
|
||||||
|
tags:
|
||||||
|
- purge
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/parameters/requestId'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Get purge job's schedule.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/ExecHistory'
|
||||||
|
'401':
|
||||||
|
$ref: '#/responses/401'
|
||||||
|
'403':
|
||||||
|
$ref: '#/responses/403'
|
||||||
|
'500':
|
||||||
|
$ref: '#/responses/500'
|
||||||
|
post:
|
||||||
|
summary: Create a purge job schedule.
|
||||||
|
description: |
|
||||||
|
This endpoint is for update purge job schedule.
|
||||||
|
operationId: createPurgeSchedule
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/parameters/requestId'
|
||||||
|
- name: schedule
|
||||||
|
in: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/Schedule'
|
||||||
|
description: |
|
||||||
|
The purge job's schedule, it is a json object. |
|
||||||
|
The sample format is |
|
||||||
|
{"parameters":{"audit_retention_hour":168,"dry_run":true, "include_operations":"create,delete,pull"},"schedule":{"type":"Hourly","cron":"0 0 * * * *"}} |
|
||||||
|
the include_operation should be a comma separated string, e.g. create,delete,pull, if it is empty, no operation will be purged.
|
||||||
|
tags:
|
||||||
|
- purge
|
||||||
|
responses:
|
||||||
|
'201':
|
||||||
|
$ref: '#/responses/201'
|
||||||
|
'400':
|
||||||
|
$ref: '#/responses/400'
|
||||||
|
'401':
|
||||||
|
$ref: '#/responses/401'
|
||||||
|
'403':
|
||||||
|
$ref: '#/responses/403'
|
||||||
|
'500':
|
||||||
|
$ref: '#/responses/500'
|
||||||
|
put:
|
||||||
|
summary: Update purge job's schedule.
|
||||||
|
description: |
|
||||||
|
This endpoint is for update purge job schedule.
|
||||||
|
operationId: updatePurgeSchedule
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/parameters/requestId'
|
||||||
|
- name: schedule
|
||||||
|
in: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/Schedule'
|
||||||
|
description: |
|
||||||
|
The purge job's schedule, it is a json object. |
|
||||||
|
The sample format is |
|
||||||
|
{"parameters":{"audit_retention_hour":168,"dry_run":true, "include_operations":"create,delete,pull"},"schedule":{"type":"Hourly","cron":"0 0 * * * *"}} |
|
||||||
|
the include_operation should be a comma separated string, e.g. create,delete,pull, if it is empty, no operation will be purged.
|
||||||
|
tags:
|
||||||
|
- purge
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Updated purge's schedule successfully.
|
||||||
|
'400':
|
||||||
|
$ref: '#/responses/400'
|
||||||
|
'401':
|
||||||
|
$ref: '#/responses/401'
|
||||||
|
'403':
|
||||||
|
$ref: '#/responses/403'
|
||||||
|
'500':
|
||||||
|
$ref: '#/responses/500'
|
||||||
|
|
||||||
/system/CVEAllowlist:
|
/system/CVEAllowlist:
|
||||||
get:
|
get:
|
||||||
summary: Get the system level allowlist of CVE.
|
summary: Get the system level allowlist of CVE.
|
||||||
@ -5523,6 +5687,13 @@ parameters:
|
|||||||
required: true
|
required: true
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
|
purgeId:
|
||||||
|
name: purge_id
|
||||||
|
in: path
|
||||||
|
description: The ID of the purge log
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
labelId:
|
labelId:
|
||||||
name: label_id
|
name: label_id
|
||||||
in: path
|
in: path
|
||||||
@ -7224,6 +7395,37 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
format: date-time
|
format: date-time
|
||||||
description: the update time of gc job.
|
description: the update time of gc job.
|
||||||
|
ExecHistory:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
description: the id of purge job.
|
||||||
|
job_name:
|
||||||
|
type: string
|
||||||
|
description: the job name of purge job.
|
||||||
|
job_kind:
|
||||||
|
type: string
|
||||||
|
description: the job kind of purge job.
|
||||||
|
job_parameters:
|
||||||
|
type: string
|
||||||
|
description: the job parameters of purge job.
|
||||||
|
schedule:
|
||||||
|
$ref: '#/definitions/ScheduleObj'
|
||||||
|
job_status:
|
||||||
|
type: string
|
||||||
|
description: the status of purge job.
|
||||||
|
deleted:
|
||||||
|
type: boolean
|
||||||
|
description: if purge job was deleted.
|
||||||
|
creation_time:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
description: the creation time of purge job.
|
||||||
|
update_time:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
description: the update time of purge job.
|
||||||
Schedule:
|
Schedule:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
28
src/controller/jobservice/model.go
Normal file
28
src/controller/jobservice/model.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// 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 jobservice
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
// Execution model for replication
|
||||||
|
type Execution struct {
|
||||||
|
ID int64
|
||||||
|
Status string
|
||||||
|
StatusMessage string
|
||||||
|
Trigger string
|
||||||
|
ExtraAttrs map[string]interface{}
|
||||||
|
StartTime time.Time
|
||||||
|
EndTime time.Time
|
||||||
|
}
|
@ -308,8 +308,8 @@ func (bs *Bootstrap) loadAndRunRedisWorkerPool(
|
|||||||
job.SampleJob: (*sample.Job)(nil),
|
job.SampleJob: (*sample.Job)(nil),
|
||||||
// Functional jobs
|
// Functional jobs
|
||||||
job.ImageScanJob: (*scan.Job)(nil),
|
job.ImageScanJob: (*scan.Job)(nil),
|
||||||
job.GarbageCollection: (*gc.GarbageCollector)(nil),
|
|
||||||
job.PurgeAudit: (*purge.Job)(nil),
|
job.PurgeAudit: (*purge.Job)(nil),
|
||||||
|
job.GarbageCollection: (*gc.GarbageCollector)(nil),
|
||||||
job.Replication: (*replication.Replication)(nil),
|
job.Replication: (*replication.Replication)(nil),
|
||||||
job.Retention: (*retention.Job)(nil),
|
job.Retention: (*retention.Job)(nil),
|
||||||
scheduler.JobNameScheduler: (*scheduler.PeriodicJob)(nil),
|
scheduler.JobNameScheduler: (*scheduler.PeriodicJob)(nil),
|
||||||
|
@ -14,7 +14,11 @@
|
|||||||
|
|
||||||
package lib
|
package lib
|
||||||
|
|
||||||
import "strings"
|
import (
|
||||||
|
"golang.org/x/text/cases"
|
||||||
|
"golang.org/x/text/language"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
// TrimsLineBreaks trims line breaks in string.
|
// TrimsLineBreaks trims line breaks in string.
|
||||||
func TrimLineBreaks(s string) string {
|
func TrimLineBreaks(s string) string {
|
||||||
@ -22,3 +26,9 @@ func TrimLineBreaks(s string) string {
|
|||||||
escaped = strings.ReplaceAll(escaped, "\r", "")
|
escaped = strings.ReplaceAll(escaped, "\r", "")
|
||||||
return escaped
|
return escaped
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Title uppercase the first character, and lower case the rest, for example covert MANUAL to Manual
|
||||||
|
func Title(s string) string {
|
||||||
|
title := cases.Title(language.Und)
|
||||||
|
return title.String(strings.ToLower(s))
|
||||||
|
}
|
||||||
|
@ -32,3 +32,23 @@ def
|
|||||||
actual := TrimLineBreaks(s)
|
actual := TrimLineBreaks(s)
|
||||||
assert.Equal(expect, actual, "should trim line breaks")
|
assert.Equal(expect, actual, "should trim line breaks")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTitle(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
s string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{"upper case", args{"MANUAL"}, "Manual"},
|
||||||
|
{"lower case", args{"manual"}, "Manual"},
|
||||||
|
{"empty", args{""}, ""},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
assert.Equalf(t, tt.want, Title(tt.args.s), "Title(%v)", tt.args.s)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -114,7 +114,13 @@ func (s *scheduler) Schedule(ctx context.Context, vendorType string, vendorID in
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
sched.CallbackFuncParam = string(paramsData)
|
sched.CallbackFuncParam = string(paramsData)
|
||||||
|
params := map[string]interface{}{}
|
||||||
|
if len(paramsData) > 0 {
|
||||||
|
err = json.Unmarshal(paramsData, ¶ms)
|
||||||
|
if err != nil {
|
||||||
|
log.Debugf("current paramsData is not a json string")
|
||||||
|
}
|
||||||
|
}
|
||||||
extrasData, err := json.Marshal(extraAttrs)
|
extrasData, err := json.Marshal(extraAttrs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -129,7 +135,7 @@ func (s *scheduler) Schedule(ctx context.Context, vendorType string, vendorID in
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
execID, err := s.execMgr.Create(ctx, JobNameScheduler, id, task.ExecutionTriggerManual)
|
execID, err := s.execMgr.Create(ctx, JobNameScheduler, id, task.ExecutionTriggerManual, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ func (s *schedulerTestSuite) TestSchedule() {
|
|||||||
|
|
||||||
// failed to submit to jobservice
|
// failed to submit to jobservice
|
||||||
s.dao.On("Create", mock.Anything, mock.Anything).Return(int64(1), nil)
|
s.dao.On("Create", mock.Anything, mock.Anything).Return(int64(1), nil)
|
||||||
s.execMgr.On("Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(int64(1), nil)
|
s.execMgr.On("Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(int64(1), nil)
|
||||||
s.taskMgr.On("Create", mock.Anything, mock.Anything, mock.Anything).Return(int64(1), nil)
|
s.taskMgr.On("Create", mock.Anything, mock.Anything, mock.Anything).Return(int64(1), nil)
|
||||||
s.taskMgr.On("Get", mock.Anything, mock.Anything).Return(&task.Task{
|
s.taskMgr.On("Get", mock.Anything, mock.Anything).Return(&task.Task{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
@ -84,7 +84,7 @@ func (s *schedulerTestSuite) TestSchedule() {
|
|||||||
s.SetupTest()
|
s.SetupTest()
|
||||||
|
|
||||||
// pass
|
// pass
|
||||||
s.execMgr.On("Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(int64(1), nil)
|
s.execMgr.On("Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(int64(1), nil)
|
||||||
s.dao.On("Create", mock.Anything, mock.Anything).Return(int64(1), nil)
|
s.dao.On("Create", mock.Anything, mock.Anything).Return(int64(1), nil)
|
||||||
s.taskMgr.On("Create", mock.Anything, mock.Anything, mock.Anything).Return(int64(1), nil)
|
s.taskMgr.On("Create", mock.Anything, mock.Anything, mock.Anything).Return(int64(1), nil)
|
||||||
s.taskMgr.On("Get", mock.Anything, mock.Anything).Return(&task.Task{
|
s.taskMgr.On("Get", mock.Anything, mock.Anything).Return(&task.Task{
|
||||||
|
@ -64,6 +64,7 @@ func New() http.Handler {
|
|||||||
HealthAPI: newHealthAPI(),
|
HealthAPI: newHealthAPI(),
|
||||||
StatisticAPI: newStatisticAPI(),
|
StatisticAPI: newStatisticAPI(),
|
||||||
ProjectMetadataAPI: newProjectMetadaAPI(),
|
ProjectMetadataAPI: newProjectMetadaAPI(),
|
||||||
|
PurgeAPI: newPurgeAPI(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
57
src/server/v2.0/handler/model/jobservice.go
Normal file
57
src/server/v2.0/handler/model/jobservice.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// 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 model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/go-openapi/strfmt"
|
||||||
|
"github.com/goharbor/harbor/src/lib"
|
||||||
|
"github.com/goharbor/harbor/src/server/v2.0/models"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ExecHistory execution history
|
||||||
|
type ExecHistory struct {
|
||||||
|
Schedule *ScheduleParam `json:"schedule"`
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Name string `json:"job_name"`
|
||||||
|
Kind string `json:"job_kind"`
|
||||||
|
Parameters string `json:"job_parameters"`
|
||||||
|
Status string `json:"job_status"`
|
||||||
|
UUID string `json:"-"`
|
||||||
|
Deleted bool `json:"deleted"`
|
||||||
|
CreationTime time.Time `json:"creation_time"`
|
||||||
|
UpdateTime time.Time `json:"update_time"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToSwagger converts the history to the swagger model
|
||||||
|
func (h *ExecHistory) ToSwagger() *models.ExecHistory {
|
||||||
|
return &models.ExecHistory{
|
||||||
|
ID: h.ID,
|
||||||
|
JobName: h.Name,
|
||||||
|
JobKind: h.Kind,
|
||||||
|
JobParameters: h.Parameters,
|
||||||
|
Deleted: h.Deleted,
|
||||||
|
JobStatus: h.Status,
|
||||||
|
Schedule: &models.ScheduleObj{
|
||||||
|
// covert MANUAL to Manual because the type of the ScheduleObj
|
||||||
|
// must be 'Hourly', 'Daily', 'Weekly', 'Custom', 'Manual' and 'None'
|
||||||
|
Type: lib.Title(strings.ToLower(h.Schedule.Type)),
|
||||||
|
Cron: h.Schedule.Cron,
|
||||||
|
},
|
||||||
|
CreationTime: strfmt.DateTime(h.CreationTime),
|
||||||
|
UpdateTime: strfmt.DateTime(h.UpdateTime),
|
||||||
|
}
|
||||||
|
}
|
301
src/server/v2.0/handler/purge.go
Normal file
301
src/server/v2.0/handler/purge.go
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
// 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 handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/go-openapi/runtime/middleware"
|
||||||
|
"github.com/go-openapi/strfmt"
|
||||||
|
"github.com/goharbor/harbor/src/common"
|
||||||
|
"github.com/goharbor/harbor/src/common/rbac"
|
||||||
|
"github.com/goharbor/harbor/src/controller/jobservice"
|
||||||
|
pg "github.com/goharbor/harbor/src/controller/purge"
|
||||||
|
"github.com/goharbor/harbor/src/controller/task"
|
||||||
|
"github.com/goharbor/harbor/src/lib/errors"
|
||||||
|
"github.com/goharbor/harbor/src/lib/q"
|
||||||
|
taskPkg "github.com/goharbor/harbor/src/pkg/task"
|
||||||
|
"github.com/goharbor/harbor/src/server/v2.0/handler/model"
|
||||||
|
"github.com/goharbor/harbor/src/server/v2.0/models"
|
||||||
|
"github.com/goharbor/harbor/src/server/v2.0/restapi/operations/purge"
|
||||||
|
operation "github.com/goharbor/harbor/src/server/v2.0/restapi/operations/purge"
|
||||||
|
"path"
|
||||||
|
)
|
||||||
|
|
||||||
|
type purgeAPI struct {
|
||||||
|
BaseAPI
|
||||||
|
purgeCtr pg.Controller
|
||||||
|
schedulerCtl jobservice.SchedulerController
|
||||||
|
taskCtl task.Controller
|
||||||
|
executionCtl task.ExecutionController
|
||||||
|
}
|
||||||
|
|
||||||
|
func newPurgeAPI() *purgeAPI {
|
||||||
|
return &purgeAPI{
|
||||||
|
purgeCtr: pg.Ctrl,
|
||||||
|
schedulerCtl: jobservice.SchedulerCtl,
|
||||||
|
taskCtl: task.Ctl,
|
||||||
|
executionCtl: task.ExecutionCtl,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *purgeAPI) CreatePurgeSchedule(ctx context.Context, params purge.CreatePurgeScheduleParams) middleware.Responder {
|
||||||
|
if err := p.RequireSystemAccess(ctx, rbac.ActionCreate, rbac.ResourcePurgeAuditLog); err != nil {
|
||||||
|
return p.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
if err := verifyCreateRequest(params); err != nil {
|
||||||
|
return p.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
id, err := p.kick(ctx, pg.VendorType, params.Schedule.Schedule.Type, params.Schedule.Schedule.Cron, params.Schedule.Parameters)
|
||||||
|
if err != nil {
|
||||||
|
return p.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
location := path.Join(params.HTTPRequest.URL.Path, fmt.Sprintf("../%d", id))
|
||||||
|
return purge.NewCreatePurgeScheduleCreated().WithLocation(location)
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyCreateRequest(params purge.CreatePurgeScheduleParams) error {
|
||||||
|
if params.Schedule == nil || params.Schedule.Schedule == nil {
|
||||||
|
return errors.BadRequestError(fmt.Errorf("schedule cann't be empty"))
|
||||||
|
}
|
||||||
|
if len(params.Schedule.Parameters) == 0 {
|
||||||
|
return errors.BadRequestError(fmt.Errorf("schedule parameter cann't be empty"))
|
||||||
|
}
|
||||||
|
if _, exist := params.Schedule.Parameters[common.PurgeAuditRetentionHour]; !exist {
|
||||||
|
return errors.BadRequestError(fmt.Errorf("audit_retention_hour should provide"))
|
||||||
|
}
|
||||||
|
if _, exist := params.Schedule.Parameters[common.PurgeAuditIncludeOperations]; !exist {
|
||||||
|
return errors.BadRequestError(fmt.Errorf("include_operations should provide"))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *purgeAPI) kick(ctx context.Context, vendorType string, scheType string, cron string, parameters map[string]interface{}) (int64, error) {
|
||||||
|
if parameters == nil {
|
||||||
|
parameters = make(map[string]interface{})
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
var id int64
|
||||||
|
|
||||||
|
policy := pg.JobPolicy{
|
||||||
|
ExtraAttrs: parameters,
|
||||||
|
}
|
||||||
|
if dryRun, ok := parameters[common.PurgeAuditDryRun].(bool); ok {
|
||||||
|
policy.DryRun = dryRun
|
||||||
|
}
|
||||||
|
if includeOperations, ok := parameters[common.PurgeAuditIncludeOperations].(string); ok {
|
||||||
|
policy.IncludeOperations = includeOperations
|
||||||
|
}
|
||||||
|
if retentionHour, ok := parameters[common.PurgeAuditRetentionHour]; ok {
|
||||||
|
if rh, ok := retentionHour.(json.Number); ok {
|
||||||
|
ret, err := rh.Int64()
|
||||||
|
if err != nil {
|
||||||
|
return 0, errors.BadRequestError(fmt.Errorf("failed to convert audit_retention_hour, error: %v", err))
|
||||||
|
}
|
||||||
|
policy.RetentionHour = int(ret)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch scheType {
|
||||||
|
case ScheduleManual:
|
||||||
|
id, err = p.purgeCtr.Start(ctx, policy, taskPkg.ExecutionTriggerManual)
|
||||||
|
case ScheduleNone:
|
||||||
|
// delete the schedule of purge
|
||||||
|
err = p.schedulerCtl.Delete(ctx, vendorType)
|
||||||
|
case ScheduleHourly, ScheduleDaily, ScheduleWeekly, ScheduleCustom:
|
||||||
|
err = p.updateSchedule(ctx, vendorType, scheType, cron, policy, parameters)
|
||||||
|
}
|
||||||
|
return id, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *purgeAPI) updateSchedule(ctx context.Context, vendorType, cronType, cron string, policy pg.JobPolicy, extraParams map[string]interface{}) error {
|
||||||
|
if err := p.schedulerCtl.Delete(ctx, vendorType); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return p.createSchedule(ctx, vendorType, cronType, cron, policy, extraParams)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *purgeAPI) GetPurgeHistory(ctx context.Context, params purge.GetPurgeHistoryParams) middleware.Responder {
|
||||||
|
if err := p.RequireSystemAccess(ctx, rbac.ActionList, rbac.ResourcePurgeAuditLog); err != nil {
|
||||||
|
return p.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
query, err := p.BuildQuery(ctx, params.Q, params.Sort, params.Page, params.PageSize)
|
||||||
|
query.Keywords["VendorType"] = pg.VendorType
|
||||||
|
if err != nil {
|
||||||
|
return p.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
total, err := p.executionCtl.Count(ctx, query)
|
||||||
|
if err != nil {
|
||||||
|
return p.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
execs, err := p.executionCtl.List(ctx, query)
|
||||||
|
if err != nil {
|
||||||
|
p.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var hs []*model.ExecHistory
|
||||||
|
for _, exec := range execs {
|
||||||
|
extraAttrsString, err := json.Marshal(exec.ExtraAttrs)
|
||||||
|
if err != nil {
|
||||||
|
return p.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
hs = append(hs, &model.ExecHistory{
|
||||||
|
ID: exec.ID,
|
||||||
|
Name: pg.VendorType,
|
||||||
|
Kind: exec.Trigger,
|
||||||
|
Parameters: string(extraAttrsString),
|
||||||
|
Schedule: &model.ScheduleParam{
|
||||||
|
Type: exec.Trigger,
|
||||||
|
},
|
||||||
|
Status: exec.Status,
|
||||||
|
CreationTime: exec.StartTime,
|
||||||
|
UpdateTime: exec.EndTime,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
var results []*models.ExecHistory
|
||||||
|
for _, h := range hs {
|
||||||
|
results = append(results, h.ToSwagger())
|
||||||
|
}
|
||||||
|
|
||||||
|
return operation.NewGetPurgeHistoryOK().
|
||||||
|
WithXTotalCount(total).
|
||||||
|
WithLink(p.Links(ctx, params.HTTPRequest.URL, total, query.PageNumber, query.PageSize).String()).
|
||||||
|
WithPayload(results)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *purgeAPI) GetPurgeJob(ctx context.Context, params purge.GetPurgeJobParams) middleware.Responder {
|
||||||
|
if err := p.RequireSystemAccess(ctx, rbac.ActionRead, rbac.ResourcePurgeAuditLog); err != nil {
|
||||||
|
return p.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
exec, err := p.executionCtl.Get(ctx, params.PurgeID)
|
||||||
|
if err != nil {
|
||||||
|
return p.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
extraAttrsString, err := json.Marshal(exec.ExtraAttrs)
|
||||||
|
if err != nil {
|
||||||
|
return p.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res := &model.ExecHistory{
|
||||||
|
ID: exec.ID,
|
||||||
|
Name: pg.VendorType,
|
||||||
|
Kind: exec.Trigger,
|
||||||
|
Parameters: string(extraAttrsString),
|
||||||
|
Status: exec.Status,
|
||||||
|
Schedule: &model.ScheduleParam{
|
||||||
|
Type: exec.Trigger,
|
||||||
|
},
|
||||||
|
CreationTime: exec.StartTime,
|
||||||
|
UpdateTime: exec.EndTime,
|
||||||
|
}
|
||||||
|
|
||||||
|
return operation.NewGetPurgeJobOK().WithPayload(res.ToSwagger())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *purgeAPI) GetPurgeJobLog(ctx context.Context, params purge.GetPurgeJobLogParams) middleware.Responder {
|
||||||
|
if err := p.RequireSystemAccess(ctx, rbac.ActionRead, rbac.ResourcePurgeAuditLog); err != nil {
|
||||||
|
return p.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
tasks, err := p.taskCtl.List(ctx, q.New(q.KeyWords{
|
||||||
|
"ExecutionID": params.PurgeID,
|
||||||
|
"VendorType": pg.VendorType,
|
||||||
|
}))
|
||||||
|
if err != nil {
|
||||||
|
return p.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
if len(tasks) == 0 {
|
||||||
|
return p.SendError(ctx,
|
||||||
|
errors.New(nil).WithCode(errors.NotFoundCode).
|
||||||
|
WithMessage("purge job with execution ID: %d taskLog is not found", params.PurgeID))
|
||||||
|
}
|
||||||
|
taskLog, err := p.taskCtl.GetLog(ctx, tasks[0].ID)
|
||||||
|
if err != nil {
|
||||||
|
return p.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
return operation.NewGetPurgeJobLogOK().WithPayload(string(taskLog))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *purgeAPI) GetPurgeSchedule(ctx context.Context, params purge.GetPurgeScheduleParams) middleware.Responder {
|
||||||
|
if err := p.RequireSystemAccess(ctx, rbac.ActionRead, rbac.ResourcePurgeAuditLog); err != nil {
|
||||||
|
return p.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
sch, err := p.schedulerCtl.Get(ctx, pg.VendorType)
|
||||||
|
if errors.IsNotFoundErr(err) {
|
||||||
|
return operation.NewGetPurgeScheduleOK()
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return p.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
execHistory := &models.ExecHistory{
|
||||||
|
ID: sch.ID,
|
||||||
|
JobName: "",
|
||||||
|
JobKind: sch.CRON,
|
||||||
|
JobParameters: pg.String(sch.ExtraAttrs),
|
||||||
|
Deleted: false,
|
||||||
|
JobStatus: sch.Status,
|
||||||
|
Schedule: &models.ScheduleObj{
|
||||||
|
Cron: sch.CRON,
|
||||||
|
Type: sch.CRONType,
|
||||||
|
},
|
||||||
|
CreationTime: strfmt.DateTime(sch.CreationTime),
|
||||||
|
UpdateTime: strfmt.DateTime(sch.UpdateTime),
|
||||||
|
}
|
||||||
|
return operation.NewGetPurgeScheduleOK().WithPayload(execHistory)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *purgeAPI) UpdatePurgeSchedule(ctx context.Context, params purge.UpdatePurgeScheduleParams) middleware.Responder {
|
||||||
|
if err := p.RequireSystemAccess(ctx, rbac.ActionUpdate, rbac.ResourcePurgeAuditLog); err != nil {
|
||||||
|
return p.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
if err := verifyUpdateRequest(params); err != nil {
|
||||||
|
return p.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
_, err := p.kick(ctx, pg.VendorType, params.Schedule.Schedule.Type, params.Schedule.Schedule.Cron, params.Schedule.Parameters)
|
||||||
|
if err != nil {
|
||||||
|
return p.SendError(ctx, err)
|
||||||
|
}
|
||||||
|
return operation.NewUpdatePurgeScheduleOK()
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyUpdateRequest(params operation.UpdatePurgeScheduleParams) error {
|
||||||
|
if params.Schedule == nil || params.Schedule.Schedule == nil {
|
||||||
|
return errors.BadRequestError(fmt.Errorf("schedule cann't be empty"))
|
||||||
|
}
|
||||||
|
if len(params.Schedule.Parameters) == 0 {
|
||||||
|
return errors.BadRequestError(fmt.Errorf("schedule parameter cann't be empty"))
|
||||||
|
}
|
||||||
|
if _, exist := params.Schedule.Parameters[common.PurgeAuditRetentionHour]; !exist {
|
||||||
|
return errors.BadRequestError(fmt.Errorf("audit_retention_hour should provide"))
|
||||||
|
}
|
||||||
|
if _, exist := params.Schedule.Parameters[common.PurgeAuditIncludeOperations]; !exist {
|
||||||
|
return errors.BadRequestError(fmt.Errorf("include_operations should provide"))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *purgeAPI) createSchedule(ctx context.Context, vendorType string, cronType string, cron string, policy pg.JobPolicy, extraParam map[string]interface{}) error {
|
||||||
|
if cron == "" {
|
||||||
|
return errors.New(nil).WithCode(errors.BadRequestCode).
|
||||||
|
WithMessage("empty cron string for schedule")
|
||||||
|
}
|
||||||
|
_, err := p.schedulerCtl.Create(ctx, vendorType, cronType, cron, pg.SchedulerCallback, policy, extraParam)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
69
src/server/v2.0/handler/purge_test.go
Normal file
69
src/server/v2.0/handler/purge_test.go
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
// 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 handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goharbor/harbor/src/common"
|
||||||
|
"github.com/goharbor/harbor/src/server/v2.0/models"
|
||||||
|
"github.com/goharbor/harbor/src/server/v2.0/restapi/operations/purge"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_verifyUpdateRequest(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
params purge.UpdatePurgeScheduleParams
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{"normal", args{purge.UpdatePurgeScheduleParams{Schedule: &models.Schedule{Schedule: &models.ScheduleObj{}, Parameters: map[string]interface{}{common.PurgeAuditRetentionHour: "168", common.PurgeAuditIncludeOperations: "pull"}}}}, false},
|
||||||
|
{"missing_schedule", args{purge.UpdatePurgeScheduleParams{Schedule: &models.Schedule{Parameters: map[string]interface{}{common.PurgeAuditRetentionHour: "168", common.PurgeAuditIncludeOperations: "pull"}}}}, true},
|
||||||
|
{"missing_retention_hour", args{purge.UpdatePurgeScheduleParams{Schedule: &models.Schedule{Schedule: &models.ScheduleObj{}, Parameters: map[string]interface{}{common.PurgeAuditIncludeOperations: "pull"}}}}, true},
|
||||||
|
{"missing_operations", args{purge.UpdatePurgeScheduleParams{Schedule: &models.Schedule{Schedule: &models.ScheduleObj{}, Parameters: map[string]interface{}{common.PurgeAuditRetentionHour: "168"}}}}, true},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
err := verifyUpdateRequest(tt.args.params)
|
||||||
|
if tt.wantErr != (err != nil) {
|
||||||
|
t.Error("test failed")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func Test_verifyCreateRequest(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
params purge.CreatePurgeScheduleParams
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{"normal", args{purge.CreatePurgeScheduleParams{Schedule: &models.Schedule{Schedule: &models.ScheduleObj{}, Parameters: map[string]interface{}{common.PurgeAuditRetentionHour: "168", common.PurgeAuditIncludeOperations: "pull"}}}}, false},
|
||||||
|
{"missing_schedule", args{purge.CreatePurgeScheduleParams{Schedule: &models.Schedule{Parameters: map[string]interface{}{common.PurgeAuditRetentionHour: "168", common.PurgeAuditIncludeOperations: "pull"}}}}, true},
|
||||||
|
{"missing_retention_hour", args{purge.CreatePurgeScheduleParams{Schedule: &models.Schedule{Schedule: &models.ScheduleObj{}, Parameters: map[string]interface{}{common.PurgeAuditIncludeOperations: "pull"}}}}, true},
|
||||||
|
{"missing_operations", args{purge.CreatePurgeScheduleParams{Schedule: &models.Schedule{Schedule: &models.ScheduleObj{}, Parameters: map[string]interface{}{common.PurgeAuditRetentionHour: "168"}}}}, true},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
err := verifyCreateRequest(tt.args.params)
|
||||||
|
if tt.wantErr != (err != nil) {
|
||||||
|
t.Error("test failed")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -29,3 +29,4 @@ package controller
|
|||||||
//go:generate mockery --case snake --dir ../../controller/user --name Controller --output ./user --outpkg user
|
//go:generate mockery --case snake --dir ../../controller/user --name Controller --output ./user --outpkg user
|
||||||
//go:generate mockery --case snake --dir ../../controller/repository --name Controller --output ./repository --outpkg repository
|
//go:generate mockery --case snake --dir ../../controller/repository --name Controller --output ./repository --outpkg repository
|
||||||
//go:generate mockery --case snake --dir ../../controller/purge --name Controller --output ./purge --outpkg purge
|
//go:generate mockery --case snake --dir ../../controller/purge --name Controller --output ./purge --outpkg purge
|
||||||
|
//go:generate mockery --case snake --dir ../../controller/jobservice --name SchedulerController --output ./jobservice --outpkg jobservice
|
||||||
|
84
src/testing/controller/jobservice/execution_controller.go
Normal file
84
src/testing/controller/jobservice/execution_controller.go
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// Code generated by mockery v2.1.0. DO NOT EDIT.
|
||||||
|
|
||||||
|
package jobservice
|
||||||
|
|
||||||
|
import (
|
||||||
|
context "context"
|
||||||
|
|
||||||
|
jobservice "github.com/goharbor/harbor/src/controller/jobservice"
|
||||||
|
mock "github.com/stretchr/testify/mock"
|
||||||
|
|
||||||
|
q "github.com/goharbor/harbor/src/lib/q"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ExecutionController is an autogenerated mock type for the ExecutionController type
|
||||||
|
type ExecutionController struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count provides a mock function with given fields: ctx, vendorType, query
|
||||||
|
func (_m *ExecutionController) Count(ctx context.Context, vendorType string, query *q.Query) (int64, error) {
|
||||||
|
ret := _m.Called(ctx, vendorType, query)
|
||||||
|
|
||||||
|
var r0 int64
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, string, *q.Query) int64); ok {
|
||||||
|
r0 = rf(ctx, vendorType, query)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Get(0).(int64)
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func(context.Context, string, *q.Query) error); ok {
|
||||||
|
r1 = rf(ctx, vendorType, query)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get provides a mock function with given fields: ctx, vendorType, executionID
|
||||||
|
func (_m *ExecutionController) Get(ctx context.Context, vendorType string, executionID int64) (*jobservice.Execution, error) {
|
||||||
|
ret := _m.Called(ctx, vendorType, executionID)
|
||||||
|
|
||||||
|
var r0 *jobservice.Execution
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, string, int64) *jobservice.Execution); ok {
|
||||||
|
r0 = rf(ctx, vendorType, executionID)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*jobservice.Execution)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func(context.Context, string, int64) error); ok {
|
||||||
|
r1 = rf(ctx, vendorType, executionID)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
// List provides a mock function with given fields: ctx, vendorType, query
|
||||||
|
func (_m *ExecutionController) List(ctx context.Context, vendorType string, query *q.Query) ([]*jobservice.Execution, error) {
|
||||||
|
ret := _m.Called(ctx, vendorType, query)
|
||||||
|
|
||||||
|
var r0 []*jobservice.Execution
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, string, *q.Query) []*jobservice.Execution); ok {
|
||||||
|
r0 = rf(ctx, vendorType, query)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).([]*jobservice.Execution)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func(context.Context, string, *q.Query) error); ok {
|
||||||
|
r1 = rf(ctx, vendorType, query)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
74
src/testing/controller/jobservice/scheduler_controller.go
Normal file
74
src/testing/controller/jobservice/scheduler_controller.go
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// Code generated by mockery v2.1.0. DO NOT EDIT.
|
||||||
|
|
||||||
|
package jobservice
|
||||||
|
|
||||||
|
import (
|
||||||
|
context "context"
|
||||||
|
|
||||||
|
mock "github.com/stretchr/testify/mock"
|
||||||
|
|
||||||
|
scheduler "github.com/goharbor/harbor/src/pkg/scheduler"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SchedulerController is an autogenerated mock type for the SchedulerController type
|
||||||
|
type SchedulerController struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create provides a mock function with given fields: ctx, vendorType, cronType, cron, callbackFuncName, policy, extrasParam
|
||||||
|
func (_m *SchedulerController) Create(ctx context.Context, vendorType string, cronType string, cron string, callbackFuncName string, policy interface{}, extrasParam map[string]interface{}) (int64, error) {
|
||||||
|
ret := _m.Called(ctx, vendorType, cronType, cron, callbackFuncName, policy, extrasParam)
|
||||||
|
|
||||||
|
var r0 int64
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string, interface{}, map[string]interface{}) int64); ok {
|
||||||
|
r0 = rf(ctx, vendorType, cronType, cron, callbackFuncName, policy, extrasParam)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Get(0).(int64)
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func(context.Context, string, string, string, string, interface{}, map[string]interface{}) error); ok {
|
||||||
|
r1 = rf(ctx, vendorType, cronType, cron, callbackFuncName, policy, extrasParam)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete provides a mock function with given fields: ctx, vendorType
|
||||||
|
func (_m *SchedulerController) Delete(ctx context.Context, vendorType string) error {
|
||||||
|
ret := _m.Called(ctx, vendorType)
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, string) error); ok {
|
||||||
|
r0 = rf(ctx, vendorType)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get provides a mock function with given fields: ctx, vendorType
|
||||||
|
func (_m *SchedulerController) Get(ctx context.Context, vendorType string) (*scheduler.Schedule, error) {
|
||||||
|
ret := _m.Called(ctx, vendorType)
|
||||||
|
|
||||||
|
var r0 *scheduler.Schedule
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, string) *scheduler.Schedule); ok {
|
||||||
|
r0 = rf(ctx, vendorType)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*scheduler.Schedule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
|
||||||
|
r1 = rf(ctx, vendorType)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
86
src/testing/controller/jobservice/task_controller.go
Normal file
86
src/testing/controller/jobservice/task_controller.go
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
// Code generated by mockery v2.1.0. DO NOT EDIT.
|
||||||
|
|
||||||
|
package jobservice
|
||||||
|
|
||||||
|
import (
|
||||||
|
context "context"
|
||||||
|
|
||||||
|
jobservice "github.com/goharbor/harbor/src/controller/jobservice"
|
||||||
|
mock "github.com/stretchr/testify/mock"
|
||||||
|
|
||||||
|
q "github.com/goharbor/harbor/src/lib/q"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TaskController is an autogenerated mock type for the TaskController type
|
||||||
|
type TaskController struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get provides a mock function with given fields: ctx, vendorType, id
|
||||||
|
func (_m *TaskController) Get(ctx context.Context, vendorType string, id int64) (*jobservice.Task, error) {
|
||||||
|
ret := _m.Called(ctx, vendorType, id)
|
||||||
|
|
||||||
|
var r0 *jobservice.Task
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, string, int64) *jobservice.Task); ok {
|
||||||
|
r0 = rf(ctx, vendorType, id)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*jobservice.Task)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func(context.Context, string, int64) error); ok {
|
||||||
|
r1 = rf(ctx, vendorType, id)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLog provides a mock function with given fields: ctx, vendorType, id
|
||||||
|
func (_m *TaskController) GetLog(ctx context.Context, vendorType string, id int64) ([]byte, error) {
|
||||||
|
ret := _m.Called(ctx, vendorType, id)
|
||||||
|
|
||||||
|
var r0 []byte
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, string, int64) []byte); ok {
|
||||||
|
r0 = rf(ctx, vendorType, id)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).([]byte)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func(context.Context, string, int64) error); ok {
|
||||||
|
r1 = rf(ctx, vendorType, id)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
// List provides a mock function with given fields: ctx, vendorType, query
|
||||||
|
func (_m *TaskController) List(ctx context.Context, vendorType string, query *q.Query) ([]*jobservice.Task, error) {
|
||||||
|
ret := _m.Called(ctx, vendorType, query)
|
||||||
|
|
||||||
|
var r0 []*jobservice.Task
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, string, *q.Query) []*jobservice.Task); ok {
|
||||||
|
r0 = rf(ctx, vendorType, query)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).([]*jobservice.Task)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func(context.Context, string, *q.Query) error); ok {
|
||||||
|
r1 = rf(ctx, vendorType, query)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user