mirror of
https://github.com/goharbor/harbor
synced 2025-04-17 01:33:58 +00:00
Merge pull request #3687 from ywk253100/171123_trigger_api
Add replication manual trigger API & update replication/policy API docs
This commit is contained in:
commit
fa85ad6d28
|
@ -1484,7 +1484,7 @@ paths:
|
||||||
description: Create new policy.
|
description: Create new policy.
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/RepPolicyPost'
|
$ref: '#/definitions/RepPolicy'
|
||||||
tags:
|
tags:
|
||||||
- Products
|
- Products
|
||||||
responses:
|
responses:
|
||||||
|
@ -1539,10 +1539,10 @@ paths:
|
||||||
description: policy ID
|
description: policy ID
|
||||||
- name: policyupdate
|
- name: policyupdate
|
||||||
in: body
|
in: body
|
||||||
description: 'Update policy name, description, target and enablement.'
|
description: 'Updated properties of the replication policy.'
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/RepPolicyUpdate'
|
$ref: '#/definitions/RepPolicy'
|
||||||
tags:
|
tags:
|
||||||
- Products
|
- Products
|
||||||
responses:
|
responses:
|
||||||
|
@ -1560,35 +1560,27 @@ paths:
|
||||||
project and target.
|
project and target.
|
||||||
'500':
|
'500':
|
||||||
description: Unexpected internal errors.
|
description: Unexpected internal errors.
|
||||||
/policies/replication/{id}/enablement:
|
/replications:
|
||||||
put:
|
post:
|
||||||
summary: Put modifies enablement of the policy.
|
summary: Trigger the replication according to the specified policy.
|
||||||
description: |
|
description: |
|
||||||
This endpoint let user update policy enablement flag.
|
This endpoint is used to trigger a replication.
|
||||||
parameters:
|
parameters:
|
||||||
- name: id
|
- name: policy ID
|
||||||
in: path
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
required: true
|
|
||||||
description: policy ID
|
|
||||||
- name: enabledflag
|
|
||||||
in: body
|
in: body
|
||||||
description: The policy enablement flag.
|
description: The ID of replication policy.
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/RepPolicyEnablementReq'
|
$ref: '#/definitions/Replication'
|
||||||
tags:
|
tags:
|
||||||
- Products
|
- Products
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: Update job policy enablement successfully.
|
description: Trigger the replication successfully.
|
||||||
'400':
|
|
||||||
description: Invalid enabled value.
|
|
||||||
'401':
|
'401':
|
||||||
description: User need to log in first.
|
description: User need to log in first.
|
||||||
'404':
|
'404':
|
||||||
description: The specific repository ID's policy does not exist.
|
description: The policy does not exist.
|
||||||
'500':
|
'500':
|
||||||
description: Unexpected internal errors.
|
description: Unexpected internal errors.
|
||||||
/targets:
|
/targets:
|
||||||
|
@ -2376,27 +2368,22 @@ definitions:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
description: The policy ID.
|
description: The policy ID.
|
||||||
project_id:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
description: The project ID.
|
|
||||||
project_name:
|
|
||||||
type: string
|
|
||||||
description: The project name.
|
|
||||||
target_id:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
description: The target ID.
|
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
description: The policy name.
|
description: The policy name.
|
||||||
enabled:
|
|
||||||
type: integer
|
|
||||||
format: int
|
|
||||||
description: The policy's enabled status.
|
|
||||||
description:
|
description:
|
||||||
type: string
|
type: string
|
||||||
description: The description of the policy.
|
description: The description of the policy.
|
||||||
|
projects:
|
||||||
|
type: object
|
||||||
|
description: The project list that the policy applys to.
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/Project'
|
||||||
|
targets:
|
||||||
|
type: object
|
||||||
|
description: The target list.
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/RepTarget'
|
||||||
trigger:
|
trigger:
|
||||||
type: object
|
type: object
|
||||||
description: The trigger for schedule job.
|
description: The trigger for schedule job.
|
||||||
|
@ -2408,14 +2395,11 @@ definitions:
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/RepFilter'
|
$ref: '#/definitions/RepFilter'
|
||||||
replicate_existing_image_now:
|
replicate_existing_image_now:
|
||||||
type: string
|
type: boolean
|
||||||
description: Whether to replicate the existing images now.
|
description: Whether to replicate the existing images now.
|
||||||
replicate_deletion:
|
replicate_deletion:
|
||||||
type: string
|
type: boolean
|
||||||
description: Whether to replicate the deletion operation.
|
description: Whether to replicate the deletion operation.
|
||||||
start_time:
|
|
||||||
type: string
|
|
||||||
description: The start time of the policy.
|
|
||||||
creation_time:
|
creation_time:
|
||||||
type: string
|
type: string
|
||||||
description: The create time of the policy.
|
description: The create time of the policy.
|
||||||
|
@ -2425,100 +2409,27 @@ definitions:
|
||||||
error_job_count:
|
error_job_count:
|
||||||
format: int
|
format: int
|
||||||
description: The error job count number for the policy.
|
description: The error job count number for the policy.
|
||||||
deleted:
|
|
||||||
type: integer
|
|
||||||
RepPolicyPost:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
project_id:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
description: The project ID.
|
|
||||||
target_id:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
description: The target ID.
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
description: The policy name.
|
|
||||||
trigger:
|
|
||||||
type: object
|
|
||||||
description: The trigger for schedule job.
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/RepTrigger'
|
|
||||||
filters:
|
|
||||||
type: array
|
|
||||||
description: The replication policy filter array.
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/RepFilter'
|
|
||||||
replicate_existing_image_now:
|
|
||||||
type: string
|
|
||||||
description: Whether to replicate the existing images now.
|
|
||||||
replicate_deletion:
|
|
||||||
type: string
|
|
||||||
description: Whether replication deletion operation.
|
|
||||||
enabled:
|
|
||||||
type: integer
|
|
||||||
format: int
|
|
||||||
description: '1-enable, 0-disable'
|
|
||||||
RepPolicyUpdate:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
target_id:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
description: The target ID.
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
description: The policy name.
|
|
||||||
enabled:
|
|
||||||
type: integer
|
|
||||||
format: int
|
|
||||||
description: The policy's enabled status.
|
|
||||||
description:
|
|
||||||
type: string
|
|
||||||
description: The description of the policy.
|
|
||||||
trigger:
|
|
||||||
type: object
|
|
||||||
description: The trigger for schedule job.
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/RepTrigger'
|
|
||||||
filters:
|
|
||||||
type: array
|
|
||||||
description: The replication policy filter array.
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/RepFilter'
|
|
||||||
replicate_existing_image_now:
|
|
||||||
type: string
|
|
||||||
description: Whether to replicate the existing images now.
|
|
||||||
replicate_deletion:
|
|
||||||
type: string
|
|
||||||
description: Whether replication deletion operation.
|
|
||||||
RepTrigger:
|
RepTrigger:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
type:
|
kind:
|
||||||
type: string
|
type: string
|
||||||
description: The replication policy trigger type.
|
description: The replication policy trigger kind.
|
||||||
params:
|
param:
|
||||||
type: object
|
type: string
|
||||||
description: The map is the replication policy trigger parameters.
|
description: The replication policy trigger parameters.
|
||||||
RepFilter:
|
RepFilter:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
type:
|
kind:
|
||||||
type: string
|
type: string
|
||||||
description: The replication policy filter type.
|
description: The replication policy filter kind.
|
||||||
value:
|
value:
|
||||||
type: string
|
type: string
|
||||||
description: The replication policy filter value.
|
description: The replication policy filter value.
|
||||||
RepPolicyEnablementReq:
|
metadata:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
description: This map object is the replication policy filter metadata.
|
||||||
enabled:
|
|
||||||
type: integer
|
|
||||||
format: int
|
|
||||||
description: The policy enablement flag.
|
|
||||||
RepTarget:
|
RepTarget:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
@ -3001,6 +2912,12 @@ definitions:
|
||||||
type: integer
|
type: integer
|
||||||
description: The offest in seconds of UTC 0 o'clock, only valid when the policy type is "daily"
|
description: The offest in seconds of UTC 0 o'clock, only valid when the policy type is "daily"
|
||||||
description: The parameters of the policy, the values are dependant on the type of the policy.
|
description: The parameters of the policy, the values are dependant on the type of the policy.
|
||||||
|
Replication:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
policy_id:
|
||||||
|
type: integer
|
||||||
|
description: The ID of replication policy
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -129,6 +129,7 @@ func init() {
|
||||||
beego.Router("/api/configurations", &ConfigAPI{})
|
beego.Router("/api/configurations", &ConfigAPI{})
|
||||||
beego.Router("/api/configurations/reset", &ConfigAPI{}, "post:Reset")
|
beego.Router("/api/configurations/reset", &ConfigAPI{}, "post:Reset")
|
||||||
beego.Router("/api/email/ping", &EmailAPI{}, "post:Ping")
|
beego.Router("/api/email/ping", &EmailAPI{}, "post:Ping")
|
||||||
|
beego.Router("/api/replications", &ReplicationAPI{})
|
||||||
|
|
||||||
_ = updateInitPassword(1, "Harbor12345")
|
_ = updateInitPassword(1, "Harbor12345")
|
||||||
|
|
||||||
|
|
31
src/ui/api/models/replication.go
Normal file
31
src/ui/api/models/replication.go
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/astaxie/beego/validation"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Replication defines the properties of model used in replication API
|
||||||
|
type Replication struct {
|
||||||
|
PolicyID int64 `json:"policy_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid ...
|
||||||
|
func (r *Replication) Valid(v *validation.Validation) {
|
||||||
|
if r.PolicyID <= 0 {
|
||||||
|
v.SetError("policy_id", "invalid value")
|
||||||
|
}
|
||||||
|
}
|
63
src/ui/api/replication.go
Normal file
63
src/ui/api/replication.go
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/vmware/harbor/src/replication/core"
|
||||||
|
"github.com/vmware/harbor/src/ui/api/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ReplicationAPI handles API calls for replication
|
||||||
|
type ReplicationAPI struct {
|
||||||
|
BaseController
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare does authentication and authorization works
|
||||||
|
func (r *ReplicationAPI) Prepare() {
|
||||||
|
r.BaseController.Prepare()
|
||||||
|
if !r.SecurityCtx.IsAuthenticated() {
|
||||||
|
r.HandleUnauthorized()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !r.SecurityCtx.IsSysAdmin() {
|
||||||
|
r.HandleForbidden(r.SecurityCtx.GetUsername())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Post trigger a replication according to the specified policy
|
||||||
|
func (r *ReplicationAPI) Post() {
|
||||||
|
replication := &models.Replication{}
|
||||||
|
r.DecodeJSONReqAndValidate(replication)
|
||||||
|
|
||||||
|
policy, err := core.DefaultController.GetPolicy(replication.PolicyID)
|
||||||
|
if err != nil {
|
||||||
|
r.HandleInternalServerError(fmt.Sprintf("failed to get replication policy %d: %v", replication.PolicyID, err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if policy.ID == 0 {
|
||||||
|
r.HandleNotFound(fmt.Sprintf("replication policy %d not found", replication.PolicyID))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = core.DefaultController.Replicate(replication.PolicyID); err != nil {
|
||||||
|
r.HandleInternalServerError(fmt.Sprintf("failed to trigger the replication policy %d: %v", replication.PolicyID, err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
92
src/ui/api/replication_test.go
Normal file
92
src/ui/api/replication_test.go
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/vmware/harbor/src/common/dao"
|
||||||
|
"github.com/vmware/harbor/src/common/models"
|
||||||
|
"github.com/vmware/harbor/src/replication"
|
||||||
|
api_models "github.com/vmware/harbor/src/ui/api/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
replicationAPIBaseURL = "/api/replications"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestReplicationAPIPost(t *testing.T) {
|
||||||
|
targetID, err := dao.AddRepTarget(
|
||||||
|
models.RepTarget{
|
||||||
|
Name: "test_replication_target",
|
||||||
|
URL: "127.0.0.1",
|
||||||
|
Username: "username",
|
||||||
|
Password: "password",
|
||||||
|
})
|
||||||
|
require.Nil(t, err)
|
||||||
|
defer dao.DeleteRepTarget(targetID)
|
||||||
|
|
||||||
|
policyID, err := dao.AddRepPolicy(
|
||||||
|
models.RepPolicy{
|
||||||
|
Name: "test_replication_policy",
|
||||||
|
ProjectID: 1,
|
||||||
|
TargetID: targetID,
|
||||||
|
Trigger: fmt.Sprintf("{\"kind\":\"%s\"}", replication.TriggerKindManual),
|
||||||
|
})
|
||||||
|
require.Nil(t, err)
|
||||||
|
defer dao.DeleteRepPolicy(policyID)
|
||||||
|
|
||||||
|
cases := []*codeCheckingCase{
|
||||||
|
// 401
|
||||||
|
&codeCheckingCase{
|
||||||
|
request: &testingRequest{
|
||||||
|
method: http.MethodPost,
|
||||||
|
url: replicationAPIBaseURL,
|
||||||
|
bodyJSON: &api_models.Replication{
|
||||||
|
PolicyID: policyID,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
code: http.StatusUnauthorized,
|
||||||
|
},
|
||||||
|
// 404
|
||||||
|
&codeCheckingCase{
|
||||||
|
request: &testingRequest{
|
||||||
|
method: http.MethodPost,
|
||||||
|
url: replicationAPIBaseURL,
|
||||||
|
bodyJSON: &api_models.Replication{
|
||||||
|
PolicyID: 10000,
|
||||||
|
},
|
||||||
|
credential: admin,
|
||||||
|
},
|
||||||
|
code: http.StatusNotFound,
|
||||||
|
},
|
||||||
|
// 200
|
||||||
|
&codeCheckingCase{
|
||||||
|
request: &testingRequest{
|
||||||
|
method: http.MethodPost,
|
||||||
|
url: replicationAPIBaseURL,
|
||||||
|
bodyJSON: &api_models.Replication{
|
||||||
|
PolicyID: policyID,
|
||||||
|
},
|
||||||
|
credential: admin,
|
||||||
|
},
|
||||||
|
code: http.StatusOK,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
runCodeCheckingCases(t, cases...)
|
||||||
|
}
|
|
@ -118,6 +118,7 @@ func initRouters() {
|
||||||
beego.Router("/api/configurations", &api.ConfigAPI{})
|
beego.Router("/api/configurations", &api.ConfigAPI{})
|
||||||
beego.Router("/api/configurations/reset", &api.ConfigAPI{}, "post:Reset")
|
beego.Router("/api/configurations/reset", &api.ConfigAPI{}, "post:Reset")
|
||||||
beego.Router("/api/statistics", &api.StatisticAPI{})
|
beego.Router("/api/statistics", &api.StatisticAPI{})
|
||||||
|
beego.Router("/api/replications", &api.ReplicationAPI{})
|
||||||
|
|
||||||
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