mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-23 00:57:44 +01:00
Add replication manual trigger API & update replication/policy API docs
This commit is contained in:
parent
b85da9679c
commit
1c338ed30b
@ -1484,7 +1484,7 @@ paths:
|
||||
description: Create new policy.
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/RepPolicyPost'
|
||||
$ref: '#/definitions/RepPolicy'
|
||||
tags:
|
||||
- Products
|
||||
responses:
|
||||
@ -1539,10 +1539,10 @@ paths:
|
||||
description: policy ID
|
||||
- name: policyupdate
|
||||
in: body
|
||||
description: 'Update policy name, description, target and enablement.'
|
||||
description: 'Updated properties of the replication policy.'
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/RepPolicyUpdate'
|
||||
$ref: '#/definitions/RepPolicy'
|
||||
tags:
|
||||
- Products
|
||||
responses:
|
||||
@ -1560,35 +1560,27 @@ paths:
|
||||
project and target.
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
/policies/replication/{id}/enablement:
|
||||
put:
|
||||
summary: Put modifies enablement of the policy.
|
||||
/replications:
|
||||
post:
|
||||
summary: Trigger the replication according to the specified policy.
|
||||
description: |
|
||||
This endpoint let user update policy enablement flag.
|
||||
This endpoint is used to trigger a replication.
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
type: integer
|
||||
format: int64
|
||||
required: true
|
||||
description: policy ID
|
||||
- name: enabledflag
|
||||
- name: policy ID
|
||||
in: body
|
||||
description: The policy enablement flag.
|
||||
description: The ID of replication policy.
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/RepPolicyEnablementReq'
|
||||
$ref: '#/definitions/Replication'
|
||||
tags:
|
||||
- Products
|
||||
responses:
|
||||
'200':
|
||||
description: Update job policy enablement successfully.
|
||||
'400':
|
||||
description: Invalid enabled value.
|
||||
description: Trigger the replication successfully.
|
||||
'401':
|
||||
description: User need to log in first.
|
||||
'404':
|
||||
description: The specific repository ID's policy does not exist.
|
||||
description: The policy does not exist.
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
/targets:
|
||||
@ -2376,27 +2368,22 @@ definitions:
|
||||
type: integer
|
||||
format: int64
|
||||
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:
|
||||
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.
|
||||
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:
|
||||
type: object
|
||||
description: The trigger for schedule job.
|
||||
@ -2408,14 +2395,11 @@ definitions:
|
||||
items:
|
||||
$ref: '#/definitions/RepFilter'
|
||||
replicate_existing_image_now:
|
||||
type: string
|
||||
type: boolean
|
||||
description: Whether to replicate the existing images now.
|
||||
replicate_deletion:
|
||||
type: string
|
||||
type: boolean
|
||||
description: Whether to replicate the deletion operation.
|
||||
start_time:
|
||||
type: string
|
||||
description: The start time of the policy.
|
||||
creation_time:
|
||||
type: string
|
||||
description: The create time of the policy.
|
||||
@ -2425,100 +2409,27 @@ definitions:
|
||||
error_job_count:
|
||||
format: int
|
||||
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:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
kind:
|
||||
type: string
|
||||
description: The replication policy trigger type.
|
||||
params:
|
||||
type: object
|
||||
description: The map is the replication policy trigger parameters.
|
||||
description: The replication policy trigger kind.
|
||||
param:
|
||||
type: string
|
||||
description: The replication policy trigger parameters.
|
||||
RepFilter:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
kind:
|
||||
type: string
|
||||
description: The replication policy filter type.
|
||||
description: The replication policy filter kind.
|
||||
value:
|
||||
type: string
|
||||
description: The replication policy filter value.
|
||||
RepPolicyEnablementReq:
|
||||
type: object
|
||||
properties:
|
||||
enabled:
|
||||
type: integer
|
||||
format: int
|
||||
description: The policy enablement flag.
|
||||
metadata:
|
||||
type: object
|
||||
description: This map object is the replication policy filter metadata.
|
||||
RepTarget:
|
||||
type: object
|
||||
properties:
|
||||
@ -3001,6 +2912,12 @@ definitions:
|
||||
type: integer
|
||||
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.
|
||||
|
||||
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/reset", &ConfigAPI{}, "post:Reset")
|
||||
beego.Router("/api/email/ping", &EmailAPI{}, "post:Ping")
|
||||
beego.Router("/api/replications", &ReplicationAPI{})
|
||||
|
||||
_ = 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/reset", &api.ConfigAPI{}, "post:Reset")
|
||||
beego.Router("/api/statistics", &api.StatisticAPI{})
|
||||
beego.Router("/api/replications", &api.ReplicationAPI{})
|
||||
|
||||
beego.Router("/api/systeminfo", &api.SystemInfoAPI{}, "get:GetGeneralInfo")
|
||||
beego.Router("/api/systeminfo/volumes", &api.SystemInfoAPI{}, "get:GetVolumeInfo")
|
||||
|
Loading…
Reference in New Issue
Block a user