feat: manager add seed peer (#1293)

Signed-off-by: Gaius <gaius.qi@gmail.com>
This commit is contained in:
Gaius 2022-05-07 17:55:26 +08:00
parent 49f9ebde68
commit 2cfbb91174
No known key found for this signature in database
GPG Key ID: 8B4E5D1290FA2FFB
44 changed files with 6144 additions and 955 deletions

View File

@ -8,6 +8,13 @@ linters-settings:
gci:
local-prefixes: d7y.io/dragonfly/v2
issues:
new: true
exclude-rules:
- linters:
- staticcheck
text: "SA1019:"
linters:
disable-all: true
enable:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -8,22 +8,20 @@ definitions:
items:
$ref: '#/definitions/model.CDNCluster'
type: array
created_at:
type: string
download_rate_limit:
type: integer
id:
type: integer
name:
type: string
scheduler_clusters:
items:
$ref: '#/definitions/model.SchedulerCluster'
type: array
seed_peer_clusters:
items:
$ref: '#/definitions/model.SeedPeerCluster'
type: array
state:
type: string
updated_at:
type: string
url:
type: string
user:
@ -31,18 +29,40 @@ definitions:
user_id:
type: integer
type: object
model.Assertion:
properties:
key:
type: string
policy:
items:
items:
type: string
type: array
type: array
policyMap:
additionalProperties:
type: integer
type: object
rm: {}
tokens:
items:
type: string
type: array
value:
type: string
type: object
model.AssertionMap:
additionalProperties:
$ref: '#/definitions/model.Assertion'
type: object
model.CDN:
properties:
cdnclusterID:
type: integer
created_at:
type: string
download_port:
type: integer
host_name:
type: string
id:
type: integer
idc:
type: string
ip:
@ -53,8 +73,6 @@ definitions:
type: integer
state:
type: string
updated_at:
type: string
type: object
model.CDNCluster:
properties:
@ -64,10 +82,6 @@ definitions:
type: string
config:
$ref: '#/definitions/model.JSONMap'
created_at:
type: string
id:
type: integer
is_default:
type: boolean
jobs:
@ -82,21 +96,13 @@ definitions:
type: array
security_group_id:
type: integer
updated_at:
type: string
type: object
model.Config:
properties:
bio:
type: string
created_at:
type: string
id:
type: integer
name:
type: string
updated_at:
type: string
user_id:
type: integer
value:
@ -115,24 +121,22 @@ definitions:
items:
$ref: '#/definitions/model.CDNCluster'
type: array
created_at:
type: string
id:
type: integer
result:
$ref: '#/definitions/model.JSONMap'
scheduler_clusters:
items:
$ref: '#/definitions/model.SchedulerCluster'
type: array
seed_peer_clusters:
items:
$ref: '#/definitions/model.SeedPeerCluster'
type: array
state:
type: string
task_id:
type: string
type:
type: string
updated_at:
type: string
user_id:
type: integer
type: object
@ -144,43 +148,29 @@ definitions:
type: string
client_secret:
type: string
created_at:
type: string
id:
type: integer
name:
type: string
redirect_url:
type: string
updated_at:
type: string
type: object
model.Scheduler:
properties:
created_at:
type: string
host_name:
type: string
id:
type: integer
idc:
type: string
ip:
type: string
location:
type: string
net_config:
$ref: '#/definitions/model.JSONMap'
net_topology:
type: string
port:
type: integer
schedulerClusterID:
type: integer
state:
type: string
updated_at:
type: string
vips:
type: string
type: object
model.SchedulerCluster:
properties:
@ -196,10 +186,6 @@ definitions:
$ref: '#/definitions/model.JSONMap'
config:
$ref: '#/definitions/model.JSONMap'
created_at:
type: string
id:
type: integer
is_default:
type: boolean
jobs:
@ -212,36 +198,28 @@ definitions:
$ref: '#/definitions/model.JSONMap'
security_group_id:
type: integer
updated_at:
type: string
seed_peer_clusters:
items:
$ref: '#/definitions/model.SeedPeerCluster'
type: array
type: object
model.SecurityGroup:
properties:
bio:
type: string
created_at:
type: string
id:
type: integer
name:
type: string
security_rules:
items:
$ref: '#/definitions/model.SecurityRule'
type: array
updated_at:
type: string
type: object
model.SecurityRule:
properties:
bio:
type: string
created_at:
type: string
domain:
type: string
id:
type: integer
name:
type: string
proxy_domain:
@ -250,8 +228,54 @@ definitions:
items:
$ref: '#/definitions/model.SecurityGroup'
type: array
updated_at:
type: object
model.SeedPeer:
properties:
download_port:
type: integer
host_name:
type: string
idc:
type: string
ip:
type: string
location:
type: string
net_topology:
type: string
port:
type: integer
seedPeerClusterID:
type: integer
state:
type: string
type:
type: string
type: object
model.SeedPeerCluster:
properties:
application_id:
type: integer
bio:
type: string
config:
$ref: '#/definitions/model.JSONMap'
is_default:
type: boolean
jobs:
items:
$ref: '#/definitions/model.Job'
type: array
name:
type: string
scheduler_clusters:
items:
$ref: '#/definitions/model.SchedulerCluster'
type: array
scopes:
$ref: '#/definitions/model.JSONMap'
security_group_id:
type: integer
type: object
model.User:
properties:
@ -259,12 +283,8 @@ definitions:
type: string
bio:
type: string
created_at:
type: string
email:
type: string
id:
type: integer
location:
type: string
name:
@ -273,8 +293,6 @@ definitions:
type: string
state:
type: string
updated_at:
type: string
type: object
rbac.Permission:
properties:
@ -305,7 +323,7 @@ definitions:
types.CDNClusterConfig:
properties:
load_limit:
maximum: 10000
maximum: 5000
minimum: 1
type: integer
net_topology:
@ -366,7 +384,6 @@ definitions:
- cdn_cluster_id
- download_port
- host_name
- idc
- ip
- port
type: object
@ -403,6 +420,10 @@ definitions:
items:
type: integer
type: array
seed_peer_cluster_ids:
items:
type: integer
type: array
type:
type: string
user_id:
@ -458,6 +479,8 @@ definitions:
type: string
scopes:
$ref: '#/definitions/types.SchedulerClusterScopes'
seed_peer_cluster_id:
type: integer
required:
- client_config
- config
@ -473,18 +496,14 @@ definitions:
type: string
location:
type: string
net_config:
additionalProperties: true
type: object
net_topology:
type: string
port:
type: integer
scheduler_cluster_id:
type: integer
vips:
type: string
required:
- host_name
- idc
- ip
- port
- scheduler_cluster_id
@ -512,6 +531,50 @@ definitions:
- domain
- name
type: object
types.CreateSeedPeerClusterRequest:
properties:
bio:
type: string
config:
$ref: '#/definitions/types.SeedPeerClusterConfig'
is_default:
type: boolean
name:
type: string
scopes:
$ref: '#/definitions/types.SeedPeerClusterScopes'
required:
- config
- name
type: object
types.CreateSeedPeerRequest:
properties:
download_port:
type: integer
host_name:
type: string
idc:
type: string
ip:
type: string
location:
type: string
net_topology:
type: string
port:
type: integer
seed_peer_cluster_id:
type: integer
type:
type: string
required:
- download_port
- host_name
- ip
- port
- seed_peer_cluster_id
- type
type: object
types.CreateV1PreheatRequest:
properties:
filter:
@ -577,7 +640,7 @@ definitions:
types.SchedulerClusterClientConfig:
properties:
load_limit:
maximum: 10000
maximum: 2000
minimum: 1
type: integer
parallel_count:
@ -601,6 +664,22 @@ definitions:
net_topology:
type: string
type: object
types.SeedPeerClusterConfig:
properties:
load_limit:
maximum: 5000
minimum: 1
type: integer
type: object
types.SeedPeerClusterScopes:
properties:
idc:
type: string
location:
type: string
net_topology:
type: string
type: object
types.SignUpRequest:
properties:
avatar:
@ -722,6 +801,8 @@ definitions:
type: string
scopes:
$ref: '#/definitions/types.SchedulerClusterScopes'
seed_peer_cluster_id:
type: integer
type: object
types.UpdateSchedulerRequest:
properties:
@ -731,17 +812,14 @@ definitions:
type: string
location:
type: string
net_config:
additionalProperties: true
type: object
net_topology:
type: string
port:
type: integer
scheduler_cluster_id:
type: integer
scheduler_id:
type: integer
vips:
type: string
type: object
types.UpdateSecurityGroupRequest:
properties:
@ -761,6 +839,38 @@ definitions:
proxy_domain:
type: string
type: object
types.UpdateSeedPeerClusterRequest:
properties:
bio:
type: string
config:
$ref: '#/definitions/types.SeedPeerClusterConfig'
is_default:
type: boolean
name:
type: string
scopes:
$ref: '#/definitions/types.SeedPeerClusterScopes'
type: object
types.UpdateSeedPeerRequest:
properties:
download_port:
type: integer
idc:
type: string
ip:
type: string
location:
type: string
net_topology:
type: string
port:
type: integer
seed_peer_cluster_id:
type: integer
type:
type: string
type: object
types.UpdateUserRequest:
properties:
avatar:
@ -1050,6 +1160,65 @@ paths:
summary: Add Scheduler to Application
tags:
- Application
/applications/{id}/seed-peer-clusters/{seed_peer_cluster_id}:
delete:
consumes:
- application/json
description: Delete SeedPeer to Application
parameters:
- description: id
in: path
name: id
required: true
type: string
- description: seed peer cluster id
in: path
name: seed_peer_cluster_id
required: true
type: string
produces:
- application/json
responses:
"200":
description: ""
"400":
description: ""
"404":
description: ""
"500":
description: ""
summary: Delete SeedPeer to Application
tags:
- Application
put:
consumes:
- application/json
description: Add SeedPeer to Application
parameters:
- description: id
in: path
name: id
required: true
type: string
- description: seed peer cluster id
in: path
name: seed_peer_cluster_id
required: true
type: string
produces:
- application/json
responses:
"200":
description: ""
"400":
description: ""
"404":
description: ""
"500":
description: ""
summary: Add SeedPeer to Application
tags:
- Application
/cdn-clusters:
get:
consumes:
@ -1896,7 +2065,7 @@ paths:
parameters:
- description: Preheat
in: body
name: CDN
name: Preheat
required: true
schema:
$ref: '#/definitions/types.CreateV1PreheatRequest'
@ -2654,6 +2823,36 @@ paths:
summary: Add SecurityRule to SecurityGroup
tags:
- SecurityGroup
/security-groups/{id}/seed-peer-clusters/{seed_peer_cluster_id}:
put:
consumes:
- application/json
description: Add SeedPeer to SecurityGroup
parameters:
- description: id
in: path
name: id
required: true
type: string
- description: seed peer cluster id
in: path
name: seed_peer_cluster_id
required: true
type: string
produces:
- application/json
responses:
"200":
description: ""
"400":
description: ""
"404":
description: ""
"500":
description: ""
summary: Add SeedPeer to SecurityGroup
tags:
- SecurityGroup
/security-rules:
get:
consumes:
@ -2828,6 +3027,362 @@ paths:
summary: Destroy SecurityRule
tags:
- SecurityRule
/seed-peer-clusters:
get:
consumes:
- application/json
description: Get SeedPeerClusters
parameters:
- default: 0
description: current page
in: query
name: page
required: true
type: integer
- default: 10
description: return max item count, default 10, max 50
in: query
maximum: 50
minimum: 2
name: per_page
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/model.SeedPeerCluster'
type: array
"400":
description: ""
"404":
description: ""
"500":
description: ""
summary: Get SeedPeerClusters
tags:
- SeedPeerCluster
post:
consumes:
- application/json
description: create by json config
parameters:
- description: DNCluster
in: body
name: SeedPeerCluster
required: true
schema:
$ref: '#/definitions/types.CreateSeedPeerClusterRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/model.SeedPeerCluster'
"400":
description: ""
"404":
description: ""
"500":
description: ""
summary: Create SeedPeerCluster
tags:
- SeedPeerCluster
/seed-peer-clusters/{id}:
delete:
consumes:
- application/json
description: Destroy by id
parameters:
- description: id
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: ""
"400":
description: ""
"404":
description: ""
"500":
description: ""
summary: Destroy SeedPeerCluster
tags:
- SeedPeerCluster
get:
consumes:
- application/json
description: Get SeedPeerCluster by id
parameters:
- description: id
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/model.SeedPeerCluster'
"400":
description: ""
"404":
description: ""
"500":
description: ""
summary: Get SeedPeerCluster
tags:
- SeedPeerCluster
patch:
consumes:
- application/json
description: Update by json config
parameters:
- description: id
in: path
name: id
required: true
type: string
- description: SeedPeerCluster
in: body
name: SeedPeerCluster
required: true
schema:
$ref: '#/definitions/types.UpdateSeedPeerClusterRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/model.SeedPeerCluster'
"400":
description: ""
"404":
description: ""
"500":
description: ""
summary: Update SeedPeerCluster
tags:
- SeedPeerCluster
/seed-peer-clusters/{id}/scheduler-clusters/{scheduler_cluster_id}:
put:
consumes:
- application/json
description: Add SchedulerCluster to SeedPeerCluster
parameters:
- description: id
in: path
name: id
required: true
type: string
- description: scheduler cluster id
in: path
name: scheduler_cluster_id
required: true
type: string
produces:
- application/json
responses:
"200":
description: ""
"400":
description: ""
"404":
description: ""
"500":
description: ""
summary: Add SchedulerCluster to SeedPeerCluster
tags:
- SeedPeerCluster
/seed-peer-clusters/{id}/seed-peers/{seed_peer_id}:
put:
consumes:
- application/json
description: Add SeedPeer to SeedPeerCluster
parameters:
- description: id
in: path
name: id
required: true
type: string
- description: seed peer id
in: path
name: seed_peer_id
required: true
type: string
produces:
- application/json
responses:
"200":
description: ""
"400":
description: ""
"404":
description: ""
"500":
description: ""
summary: Add Instance to SeedPeerCluster
tags:
- SeedPeerCluster
/seed-peers:
get:
consumes:
- application/json
description: Get SeedPeers
parameters:
- default: 0
description: current page
in: query
name: page
required: true
type: integer
- default: 10
description: return max item count, default 10, max 50
in: query
maximum: 50
minimum: 2
name: per_page
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/model.SeedPeer'
type: array
"400":
description: ""
"404":
description: ""
"500":
description: ""
summary: Get SeedPeers
tags:
- SeedPeer
post:
consumes:
- application/json
description: create by json config
parameters:
- description: SeedPeer
in: body
name: SeedPeer
required: true
schema:
$ref: '#/definitions/types.CreateSeedPeerRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/model.SeedPeer'
"400":
description: ""
"404":
description: ""
"500":
description: ""
summary: Create SeedPeer
tags:
- SeedPeer
/seed-peers/{id}:
delete:
consumes:
- application/json
description: Destroy by id
parameters:
- description: id
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: ""
"400":
description: ""
"404":
description: ""
"500":
description: ""
summary: Destroy SeedPeer
tags:
- SeedPeer
get:
consumes:
- application/json
description: Get SeedPeer by id
parameters:
- description: id
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/model.SeedPeer'
"400":
description: ""
"404":
description: ""
"500":
description: ""
summary: Get SeedPeer
tags:
- SeedPeer
patch:
consumes:
- application/json
description: Update by json config
parameters:
- description: id
in: path
name: id
required: true
type: string
- description: SeedPeer
in: body
name: SeedPeer
required: true
schema:
$ref: '#/definitions/types.UpdateSeedPeerRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/model.SeedPeer'
"400":
description: ""
"404":
description: ""
"500":
description: ""
summary: Update SeedPeer
tags:
- SeedPeer
/user/signin/{name}:
get:
consumes:
@ -2932,7 +3487,7 @@ paths:
description: OK
schema:
items:
$ref: '#/definitions/model.CDN'
$ref: '#/definitions/model.User'
type: array
"400":
description: ""
@ -2942,7 +3497,7 @@ paths:
description: ""
summary: Get Users
tags:
- CDN
- User
/users/{id}:
get:
consumes:

View File

@ -1,5 +1,5 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: d7y.io/dragonfly/v2/pkg/rpc/manager/client (interfaces: Client)
// Source: pkg/rpc/manager/client/client.go
// Package mocks is a generated GoMock package.
package mocks
@ -120,3 +120,18 @@ func (mr *MockClientMockRecorder) UpdateScheduler(arg0 interface{}) *gomock.Call
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateScheduler", reflect.TypeOf((*MockClient)(nil).UpdateScheduler), arg0)
}
// UpdateSeedPeer mocks base method.
func (m *MockClient) UpdateSeedPeer(arg0 *manager.UpdateSeedPeerRequest) (*manager.SeedPeer, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateSeedPeer", arg0)
ret0, _ := ret[0].(*manager.SeedPeer)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// UpdateSeedPeer indicates an expected call of UpdateSeedPeer.
func (mr *MockClientMockRecorder) UpdateSeedPeer(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateSeedPeer", reflect.TypeOf((*MockClient)(nil).UpdateSeedPeer), arg0)
}

View File

@ -27,17 +27,26 @@ import (
)
const (
CDNNamespace = "cdn"
SchedulerNamespace = "scheduler"
// Seed Peer prefix of cache key.
SeedPeerNamespace = "seed-peer"
// CDN prefix of cache key.
CDNNamespace = "cdn"
// Scheduler prefix of cache key.
SchedulerNamespace = "scheduler"
// Schedulers prefix of cache key.
SchedulersNamespace = "schedulers"
)
// Cache is cache client.
type Cache struct {
*cache.Cache
TTL time.Duration
}
// New cache instance
// New cache instance.
func New(cfg *config.Config) (*Cache, error) {
var localCache *cache.TinyLFU
if cfg.Cache != nil {
@ -60,18 +69,27 @@ func New(cfg *config.Config) (*Cache, error) {
}, nil
}
// Make cache key
func MakeCacheKey(namespace string, id string) string {
return fmt.Sprintf("manager:%s:%s", namespace, id)
}
// Make cache key for seed peer
func MakeSeedPeerCacheKey(hostname string, clusterID uint) string {
return MakeCacheKey(SeedPeerNamespace, fmt.Sprintf("%s-%d", hostname, clusterID))
}
// Deprecated: Use MakeSeedPeerCacheKey instead.
func MakeCDNCacheKey(hostname string, clusterID uint) string {
return MakeCacheKey(CDNNamespace, fmt.Sprintf("%s-%d", hostname, clusterID))
}
// Make cache key for scheduler
func MakeSchedulerCacheKey(hostname string, clusterID uint) string {
return MakeCacheKey(SchedulerNamespace, fmt.Sprintf("%s-%d", hostname, clusterID))
}
// Make cache key for schedulers
func MakeSchedulersCacheKey(hostname, ip string) string {
return MakeCacheKey(SchedulersNamespace, fmt.Sprintf("%s-%s", hostname, ip))
}

View File

@ -224,6 +224,60 @@ func (h *Handlers) DeleteSchedulerClusterToApplication(ctx *gin.Context) {
ctx.Status(http.StatusOK)
}
// @Summary Add SeedPeer to Application
// @Description Add SeedPeer to Application
// @Tags Application
// @Accept json
// @Produce json
// @Param id path string true "id"
// @Param seed_peer_cluster_id path string true "seed peer cluster id"
// @Success 200
// @Failure 400
// @Failure 404
// @Failure 500
// @Router /applications/{id}/seed-peer-clusters/{seed_peer_cluster_id} [put]
func (h *Handlers) AddSeedPeerClusterToApplication(ctx *gin.Context) {
var params types.AddSeedPeerClusterToApplicationParams
if err := ctx.ShouldBindUri(&params); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
if err := h.service.AddSeedPeerClusterToApplication(ctx.Request.Context(), params.ID, params.SeedPeerClusterID); err != nil {
ctx.Error(err) // nolint: errcheck
return
}
ctx.Status(http.StatusOK)
}
// @Summary Delete SeedPeer to Application
// @Description Delete SeedPeer to Application
// @Tags Application
// @Accept json
// @Produce json
// @Param id path string true "id"
// @Param seed_peer_cluster_id path string true "seed peer cluster id"
// @Success 200
// @Failure 400
// @Failure 404
// @Failure 500
// @Router /applications/{id}/seed-peer-clusters/{seed_peer_cluster_id} [delete]
func (h *Handlers) DeleteSeedPeerClusterToApplication(ctx *gin.Context) {
var params types.DeleteSeedPeerClusterToApplicationParams
if err := ctx.ShouldBindUri(&params); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
if err := h.service.DeleteSeedPeerClusterToApplication(ctx.Request.Context(), params.ID, params.SeedPeerClusterID); err != nil {
ctx.Error(err) // nolint: errcheck
return
}
ctx.Status(http.StatusOK)
}
// @Summary Add CDN to Application
// @Description Add CDN to Application
// @Tags Application

View File

@ -31,7 +31,7 @@ import (
// @Tags Preheat
// @Accept json
// @Produce json
// @Param CDN body types.CreateV1PreheatRequest true "Preheat"
// @Param Preheat body types.CreateV1PreheatRequest true "Preheat"
// @Success 200 {object} types.CreateV1PreheatResponse
// @Failure 400
// @Failure 404

View File

@ -198,6 +198,34 @@ func (h *Handlers) AddSchedulerClusterToSecurityGroup(ctx *gin.Context) {
ctx.Status(http.StatusOK)
}
// @Summary Add SeedPeer to SecurityGroup
// @Description Add SeedPeer to SecurityGroup
// @Tags SecurityGroup
// @Accept json
// @Produce json
// @Param id path string true "id"
// @Param seed_peer_cluster_id path string true "seed peer cluster id"
// @Success 200
// @Failure 400
// @Failure 404
// @Failure 500
// @Router /security-groups/{id}/seed-peer-clusters/{seed_peer_cluster_id} [put]
func (h *Handlers) AddSeedPeerClusterToSecurityGroup(ctx *gin.Context) {
var params types.AddSeedPeerClusterToSecurityGroupParams
if err := ctx.ShouldBindUri(&params); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
err := h.service.AddSeedPeerClusterToSecurityGroup(ctx.Request.Context(), params.ID, params.SeedPeerClusterID)
if err != nil {
ctx.Error(err) // nolint: errcheck
return
}
ctx.Status(http.StatusOK)
}
// @Summary Add CDN to SecurityGroup
// @Description Add CDN to SecurityGroup
// @Tags SecurityGroup

View File

@ -0,0 +1,171 @@
/*
* Copyright 2022 The Dragonfly 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 handlers
import (
"net/http"
"github.com/gin-gonic/gin"
// nolint
_ "d7y.io/dragonfly/v2/manager/model"
"d7y.io/dragonfly/v2/manager/types"
)
// @Summary Create SeedPeer
// @Description create by json config
// @Tags SeedPeer
// @Accept json
// @Produce json
// @Param SeedPeer body types.CreateSeedPeerRequest true "SeedPeer"
// @Success 200 {object} model.SeedPeer
// @Failure 400
// @Failure 404
// @Failure 500
// @Router /seed-peers [post]
func (h *Handlers) CreateSeedPeer(ctx *gin.Context) {
var json types.CreateSeedPeerRequest
if err := ctx.ShouldBindJSON(&json); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
seedPeer, err := h.service.CreateSeedPeer(ctx.Request.Context(), json)
if err != nil {
ctx.Error(err) // nolint: errcheck
return
}
ctx.JSON(http.StatusOK, seedPeer)
}
// @Summary Destroy SeedPeer
// @Description Destroy by id
// @Tags SeedPeer
// @Accept json
// @Produce json
// @Param id path string true "id"
// @Success 200
// @Failure 400
// @Failure 404
// @Failure 500
// @Router /seed-peers/{id} [delete]
func (h *Handlers) DestroySeedPeer(ctx *gin.Context) {
var params types.SeedPeerParams
if err := ctx.ShouldBindUri(&params); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
if err := h.service.DestroySeedPeer(ctx.Request.Context(), params.ID); err != nil {
ctx.Error(err) // nolint: errcheck
return
}
ctx.Status(http.StatusOK)
}
// @Summary Update SeedPeer
// @Description Update by json config
// @Tags SeedPeer
// @Accept json
// @Produce json
// @Param id path string true "id"
// @Param SeedPeer body types.UpdateSeedPeerRequest true "SeedPeer"
// @Success 200 {object} model.SeedPeer
// @Failure 400
// @Failure 404
// @Failure 500
// @Router /seed-peers/{id} [patch]
func (h *Handlers) UpdateSeedPeer(ctx *gin.Context) {
var params types.SeedPeerParams
if err := ctx.ShouldBindUri(&params); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
var json types.UpdateSeedPeerRequest
if err := ctx.ShouldBindJSON(&json); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
seedPeer, err := h.service.UpdateSeedPeer(ctx.Request.Context(), params.ID, json)
if err != nil {
ctx.Error(err) // nolint: errcheck
return
}
ctx.JSON(http.StatusOK, seedPeer)
}
// @Summary Get SeedPeer
// @Description Get SeedPeer by id
// @Tags SeedPeer
// @Accept json
// @Produce json
// @Param id path string true "id"
// @Success 200 {object} model.SeedPeer
// @Failure 400
// @Failure 404
// @Failure 500
// @Router /seed-peers/{id} [get]
func (h *Handlers) GetSeedPeer(ctx *gin.Context) {
var params types.SeedPeerParams
if err := ctx.ShouldBindUri(&params); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
seedPeer, err := h.service.GetSeedPeer(ctx.Request.Context(), params.ID)
if err != nil {
ctx.Error(err) // nolint: errcheck
return
}
ctx.JSON(http.StatusOK, seedPeer)
}
// @Summary Get SeedPeers
// @Description Get SeedPeers
// @Tags SeedPeer
// @Accept json
// @Produce json
// @Param page query int true "current page" default(0)
// @Param per_page query int true "return max item count, default 10, max 50" default(10) minimum(2) maximum(50)
// @Success 200 {object} []model.SeedPeer
// @Failure 400
// @Failure 404
// @Failure 500
// @Router /seed-peers [get]
func (h *Handlers) GetSeedPeers(ctx *gin.Context) {
var query types.GetSeedPeersQuery
if err := ctx.ShouldBindQuery(&query); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
h.setPaginationDefault(&query.Page, &query.PerPage)
seedPeers, count, err := h.service.GetSeedPeers(ctx.Request.Context(), query)
if err != nil {
ctx.Error(err) // nolint: errcheck
return
}
h.setPaginationLinkHeader(ctx, query.Page, query.PerPage, int(count))
ctx.JSON(http.StatusOK, seedPeers)
}

View File

@ -0,0 +1,225 @@
/*
* Copyright 2022 The Dragonfly 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 handlers
import (
"net/http"
"github.com/gin-gonic/gin"
// nolint
_ "d7y.io/dragonfly/v2/manager/model"
"d7y.io/dragonfly/v2/manager/types"
)
// @Summary Create SeedPeerCluster
// @Description create by json config
// @Tags SeedPeerCluster
// @Accept json
// @Produce json
// @Param SeedPeerCluster body types.CreateSeedPeerClusterRequest true "DNCluster"
// @Success 200 {object} model.SeedPeerCluster
// @Failure 400
// @Failure 404
// @Failure 500
// @Router /seed-peer-clusters [post]
func (h *Handlers) CreateSeedPeerCluster(ctx *gin.Context) {
var json types.CreateSeedPeerClusterRequest
if err := ctx.ShouldBindJSON(&json); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
seedPeerCluster, err := h.service.CreateSeedPeerCluster(ctx.Request.Context(), json)
if err != nil {
ctx.Error(err) // nolint: errcheck
return
}
ctx.JSON(http.StatusOK, seedPeerCluster)
}
// @Summary Destroy SeedPeerCluster
// @Description Destroy by id
// @Tags SeedPeerCluster
// @Accept json
// @Produce json
// @Param id path string true "id"
// @Success 200
// @Failure 400
// @Failure 404
// @Failure 500
// @Router /seed-peer-clusters/{id} [delete]
func (h *Handlers) DestroySeedPeerCluster(ctx *gin.Context) {
var params types.SeedPeerClusterParams
if err := ctx.ShouldBindUri(&params); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
if err := h.service.DestroySeedPeerCluster(ctx.Request.Context(), params.ID); err != nil {
ctx.Error(err) // nolint: errcheck
return
}
ctx.Status(http.StatusOK)
}
// @Summary Update SeedPeerCluster
// @Description Update by json config
// @Tags SeedPeerCluster
// @Accept json
// @Produce json
// @Param id path string true "id"
// @Param SeedPeerCluster body types.UpdateSeedPeerClusterRequest true "SeedPeerCluster"
// @Success 200 {object} model.SeedPeerCluster
// @Failure 400
// @Failure 404
// @Failure 500
// @Router /seed-peer-clusters/{id} [patch]
func (h *Handlers) UpdateSeedPeerCluster(ctx *gin.Context) {
var params types.SeedPeerClusterParams
if err := ctx.ShouldBindUri(&params); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
var json types.UpdateSeedPeerClusterRequest
if err := ctx.ShouldBindJSON(&json); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
seedPeerCluster, err := h.service.UpdateSeedPeerCluster(ctx.Request.Context(), params.ID, json)
if err != nil {
ctx.Error(err) // nolint: errcheck
return
}
ctx.JSON(http.StatusOK, seedPeerCluster)
}
// @Summary Get SeedPeerCluster
// @Description Get SeedPeerCluster by id
// @Tags SeedPeerCluster
// @Accept json
// @Produce json
// @Param id path string true "id"
// @Success 200 {object} model.SeedPeerCluster
// @Failure 400
// @Failure 404
// @Failure 500
// @Router /seed-peer-clusters/{id} [get]
func (h *Handlers) GetSeedPeerCluster(ctx *gin.Context) {
var params types.SeedPeerClusterParams
if err := ctx.ShouldBindUri(&params); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
seedPeerCluster, err := h.service.GetSeedPeerCluster(ctx.Request.Context(), params.ID)
if err != nil {
ctx.Error(err) // nolint: errcheck
return
}
ctx.JSON(http.StatusOK, seedPeerCluster)
}
// @Summary Get SeedPeerClusters
// @Description Get SeedPeerClusters
// @Tags SeedPeerCluster
// @Accept json
// @Produce json
// @Param page query int true "current page" default(0)
// @Param per_page query int true "return max item count, default 10, max 50" default(10) minimum(2) maximum(50)
// @Success 200 {object} []model.SeedPeerCluster
// @Failure 400
// @Failure 404
// @Failure 500
// @Router /seed-peer-clusters [get]
func (h *Handlers) GetSeedPeerClusters(ctx *gin.Context) {
var query types.GetSeedPeerClustersQuery
if err := ctx.ShouldBindQuery(&query); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
h.setPaginationDefault(&query.Page, &query.PerPage)
seedPeers, count, err := h.service.GetSeedPeerClusters(ctx.Request.Context(), query)
if err != nil {
ctx.Error(err) // nolint: errcheck
return
}
h.setPaginationLinkHeader(ctx, query.Page, query.PerPage, int(count))
ctx.JSON(http.StatusOK, seedPeers)
}
// @Summary Add Instance to SeedPeerCluster
// @Description Add SeedPeer to SeedPeerCluster
// @Tags SeedPeerCluster
// @Accept json
// @Produce json
// @Param id path string true "id"
// @Param seed_peer_id path string true "seed peer id"
// @Success 200
// @Failure 400
// @Failure 404
// @Failure 500
// @Router /seed-peer-clusters/{id}/seed-peers/{seed_peer_id} [put]
func (h *Handlers) AddSeedPeerToSeedPeerCluster(ctx *gin.Context) {
var params types.AddSeedPeerToSeedPeerClusterParams
if err := ctx.ShouldBindUri(&params); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
if err := h.service.AddSeedPeerToSeedPeerCluster(ctx.Request.Context(), params.ID, params.SeedPeerID); err != nil {
ctx.Error(err) // nolint: errcheck
return
}
ctx.Status(http.StatusOK)
}
// @Summary Add SchedulerCluster to SeedPeerCluster
// @Description Add SchedulerCluster to SeedPeerCluster
// @Tags SeedPeerCluster
// @Accept json
// @Produce json
// @Param id path string true "id"
// @Param scheduler_cluster_id path string true "scheduler cluster id"
// @Success 200
// @Failure 400
// @Failure 404
// @Failure 500
// @Router /seed-peer-clusters/{id}/scheduler-clusters/{scheduler_cluster_id} [put]
func (h *Handlers) AddSchedulerClusterToSeedPeerCluster(ctx *gin.Context) {
var params types.AddSchedulerClusterToSeedPeerClusterParams
if err := ctx.ShouldBindUri(&params); err != nil {
ctx.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()})
return
}
if err := h.service.AddSchedulerClusterToSeedPeerCluster(ctx.Request.Context(), params.ID, params.SchedulerClusterID); err != nil {
ctx.Error(err) // nolint: errcheck
return
}
ctx.Status(http.StatusOK)
}

View File

@ -90,12 +90,12 @@ func (h *Handlers) GetUser(ctx *gin.Context) {
// @Summary Get Users
// @Description Get Users
// @Tags CDN
// @Tags User
// @Accept json
// @Produce json
// @Param page query int true "current page" default(0)
// @Param per_page query int true "return max item count, default 10, max 50" default(10) minimum(2) maximum(50)
// @Success 200 {object} []model.CDN
// @Success 200 {object} []model.User
// @Failure 400
// @Failure 404
// @Failure 500

View File

@ -25,6 +25,7 @@ type Application struct {
BIO string `gorm:"column:bio;type:varchar(1024);comment:biography" json:"bio"`
UserID uint `gorm:"comment:user id" json:"user_id"`
User User `json:"user"`
SchedulerClusters []SchedulerCluster `json:"scheduler_clusters"`
SeedPeerClusters []SeedPeerCluster `json:"seed_peer_clusters"`
CDNClusters []CDNCluster `json:"cdn_clusters"`
SchedulerClusters []SchedulerCluster `json:"scheduler_clusters"`
}

View File

@ -26,6 +26,7 @@ type Job struct {
Result JSONMap `gorm:"column:result;comment:task result" json:"result"`
UserID uint `gorm:"column:user_id;comment:user id" json:"user_id"`
User User `json:"-"`
SeedPeerClusters []SeedPeerCluster `gorm:"many2many:job_seed_peer_cluster;" json:"seed_peer_clusters"`
CDNClusters []CDNCluster `gorm:"many2many:job_cdn_cluster;" json:"cdn_clusters"`
SchedulerClusters []SchedulerCluster `gorm:"many2many:job_scheduler_cluster;" json:"scheduler_clusters"`
}

View File

@ -24,10 +24,9 @@ const (
type Scheduler struct {
Model
HostName string `gorm:"column:host_name;type:varchar(256);index:uk_scheduler,unique;not null;comment:hostname" json:"host_name"`
VIPs string `gorm:"column:vips;type:varchar(1024);comment:virtual ip address" json:"vips"`
IDC string `gorm:"column:idc;type:varchar(1024);comment:internet data center" json:"idc"`
NetTopology string `gorm:"column:net_topology;type:varchar(1024);comment:network topology" json:"net_topology"`
Location string `gorm:"column:location;type:varchar(1024);comment:location" json:"location"`
NetConfig JSONMap `gorm:"column:net_config;comment:network configuration" json:"net_config"`
IP string `gorm:"column:ip;type:varchar(256);not null;comment:ip address" json:"ip"`
Port int32 `gorm:"column:port;not null;comment:grpc service listening port" json:"port"`
State string `gorm:"column:state;type:varchar(256);default:'inactive';comment:service state" json:"state"`

View File

@ -18,17 +18,18 @@ package model
type SchedulerCluster struct {
Model
Name string `gorm:"column:name;type:varchar(256);index:uk_scheduler_cluster_name,unique;not null;comment:name" json:"name"`
BIO string `gorm:"column:bio;type:varchar(1024);comment:biography" json:"bio"`
Config JSONMap `gorm:"column:config;not null;comment:configuration" json:"config"`
ClientConfig JSONMap `gorm:"column:client_config;not null;comment:client configuration" json:"client_config"`
Scopes JSONMap `gorm:"column:scopes;comment:match scopes" json:"scopes"`
IsDefault bool `gorm:"column:is_default;not null;default:false;comment:default scheduler cluster" json:"is_default"`
CDNClusters []CDNCluster `gorm:"many2many:cdn_cluster_scheduler_cluster;" json:"cdn_clusters"`
Schedulers []Scheduler `json:"-"`
ApplicationID uint `gorm:"comment:application id" json:"application_id"`
Application Application `json:"-"`
SecurityGroupID uint `gorm:"comment:security group id" json:"security_group_id"`
SecurityGroup SecurityGroup `json:"-"`
Jobs []Job `gorm:"many2many:job_scheduler_cluster;" json:"jobs"`
Name string `gorm:"column:name;type:varchar(256);index:uk_scheduler_cluster_name,unique;not null;comment:name" json:"name"`
BIO string `gorm:"column:bio;type:varchar(1024);comment:biography" json:"bio"`
Config JSONMap `gorm:"column:config;not null;comment:configuration" json:"config"`
ClientConfig JSONMap `gorm:"column:client_config;not null;comment:client configuration" json:"client_config"`
Scopes JSONMap `gorm:"column:scopes;comment:match scopes" json:"scopes"`
IsDefault bool `gorm:"column:is_default;not null;default:false;comment:default scheduler cluster" json:"is_default"`
SeedPeerClusters []SeedPeerCluster `gorm:"many2many:seed_peer_cluster_scheduler_cluster;" json:"seed_peer_clusters"`
CDNClusters []CDNCluster `gorm:"many2many:cdn_cluster_scheduler_cluster;" json:"cdn_clusters"`
Schedulers []Scheduler `json:"-"`
ApplicationID uint `gorm:"comment:application id" json:"application_id"`
Application Application `json:"-"`
SecurityGroupID uint `gorm:"comment:security group id" json:"security_group_id"`
SecurityGroup SecurityGroup `json:"-"`
Jobs []Job `gorm:"many2many:job_scheduler_cluster;" json:"jobs"`
}

View File

@ -21,6 +21,7 @@ type SecurityGroup struct {
Name string `gorm:"column:name;type:varchar(256);index:uk_security_group_name,unique;not null;comment:name" json:"name"`
BIO string `gorm:"column:bio;type:varchar(1024);comment:biography" json:"bio"`
SecurityRules []SecurityRule `gorm:"many2many:security_group_security_rule;" json:"security_rules"`
SchedulerClusters []SchedulerCluster `json:"-"`
SeedPeerClusters []SeedPeerCluster `json:"-"`
CDNClusters []CDNCluster `json:"-"`
SchedulerClusters []SchedulerCluster `json:"-"`
}

View File

@ -0,0 +1,43 @@
/*
* Copyright 2022 The Dragonfly 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
const (
SeedPeerStateActive = "active"
SeedPeerStateInactive = "inactive"
)
const (
SeedPeerTypeSuperSeed = "SuperSeed"
SeedPeerTypeStrongSeed = "StrongSeed"
SeedPeerTypeWeakSeed = "WeakSeed"
)
type SeedPeer struct {
Model
HostName string `gorm:"column:host_name;type:varchar(256);index:uk_seed_peer,unique;not null;comment:hostname" json:"host_name"`
Type string `gorm:"column:type;type:varchar(256);comment:type" json:"type"`
IDC string `gorm:"column:idc;type:varchar(1024);comment:internet data center" json:"idc"`
NetTopology string `gorm:"column:net_topology;type:varchar(1024);comment:network topology" json:"net_topology"`
Location string `gorm:"column:location;type:varchar(1024);comment:location" json:"location"`
IP string `gorm:"column:ip;type:varchar(256);not null;comment:ip address" json:"ip"`
Port int32 `gorm:"column:port;not null;comment:grpc service listening port" json:"port"`
DownloadPort int32 `gorm:"column:download_port;not null;comment:download service listening port" json:"download_port"`
State string `gorm:"column:state;type:varchar(256);default:'inactive';comment:service state" json:"state"`
SeedPeerClusterID uint `gorm:"index:uk_seed_peer,unique;not null;comment:seed peer cluster id"`
SeedPeerCluster SeedPeerCluster `json:"-"`
}

View File

@ -0,0 +1,33 @@
/*
* Copyright 2022 The Dragonfly 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
type SeedPeerCluster struct {
Model
Name string `gorm:"column:name;type:varchar(256);index:uk_seed_peer_cluster_name,unique;not null;comment:name" json:"name"`
BIO string `gorm:"column:bio;type:varchar(1024);comment:biography" json:"bio"`
Config JSONMap `gorm:"column:config;not null;comment:configuration" json:"config"`
Scopes JSONMap `gorm:"column:scopes;comment:match scopes" json:"scopes"`
IsDefault bool `gorm:"column:is_default;not null;default:false;comment:default seed peer cluster" json:"is_default"`
SchedulerClusters []SchedulerCluster `gorm:"many2many:seed_peer_cluster_scheduler_cluster;" json:"scheduler_clusters"`
SeedPeers []SeedPeer `json:"-"`
ApplicationID uint `gorm:"comment:application id" json:"application_id"`
Application Application `json:"-"`
SecurityGroupID uint `gorm:"comment:security group id" json:"security_group_id"`
SecurityGroup SecurityGroup `json:"-"`
Jobs []Job `gorm:"many2many:job_seed_peer_cluster;" json:"jobs"`
}

View File

@ -154,9 +154,29 @@ func Init(cfg *config.Config, logDir string, service service.Service, enforcer *
cs.GET("", h.GetApplications)
cs.PUT(":id/scheduler-clusters/:scheduler_cluster_id", h.AddSchedulerClusterToApplication)
cs.DELETE(":id/scheduler-clusters/:scheduler_cluster_id", h.DeleteSchedulerClusterToApplication)
cs.PUT(":id/seed-peer-clusters/:seed_peer_cluster_id", h.AddSeedPeerClusterToApplication)
cs.DELETE(":id/seed-peer-clusters/:seed_peer_cluster_id", h.DeleteSeedPeerClusterToApplication)
cs.PUT(":id/cdn-clusters/:cdn_cluster_id", h.AddCDNClusterToApplication)
cs.DELETE(":id/cdn-clusters/:cdn_cluster_id", h.DeleteCDNClusterToApplication)
// Seed Peer Cluster
spc := apiv1.Group("/seed-peer-clusters", jwt.MiddlewareFunc(), rbac)
spc.POST("", h.CreateSeedPeerCluster)
spc.DELETE(":id", h.DestroySeedPeerCluster)
spc.PATCH(":id", h.UpdateSeedPeerCluster)
spc.GET(":id", h.GetSeedPeerCluster)
spc.GET("", h.GetSeedPeerClusters)
spc.PUT(":id/seed-peers/:seed_peer_id", h.AddSeedPeerToSeedPeerCluster)
spc.PUT(":id/scheduler-clusters/:scheduler_cluster_id", h.AddSchedulerClusterToSeedPeerCluster)
// Seed Peer
sp := apiv1.Group("/seed-peers", jwt.MiddlewareFunc(), rbac)
sp.POST("", h.CreateSeedPeer)
sp.DELETE(":id", h.DestroySeedPeer)
sp.PATCH(":id", h.UpdateSeedPeer)
sp.GET(":id", h.GetSeedPeer)
sp.GET("", h.GetSeedPeers)
// CDN Cluster
cc := apiv1.Group("/cdn-clusters", jwt.MiddlewareFunc(), rbac)
cc.POST("", h.CreateCDNCluster)
@ -191,6 +211,7 @@ func Init(cfg *config.Config, logDir string, service service.Service, enforcer *
sg.GET(":id", h.GetSecurityGroup)
sg.GET("", h.GetSecurityGroups)
sg.PUT(":id/scheduler-clusters/:scheduler_cluster_id", h.AddSchedulerClusterToSecurityGroup)
sg.PUT(":id/seed-peer-clusters/:seed_peer_cluster_id", h.AddSeedPeerClusterToSecurityGroup)
sg.PUT(":id/cdn-clusters/:cdn_cluster_id", h.AddCDNClusterToSecurityGroup)
sg.PUT(":id/security-rules/:security_rule_id", h.AddSecurityRuleToSecurityGroup)
sg.DELETE(":id/security-rules/:security_rule_id", h.DestroySecurityRuleToSecurityGroup)

View File

@ -43,6 +43,7 @@ import (
"d7y.io/dragonfly/v2/pkg/rpc/manager"
)
// Default middlewares for stream.
func defaultStreamMiddleWares() []grpc.StreamServerInterceptor {
return []grpc.StreamServerInterceptor{
grpc_validator.StreamServerInterceptor(),
@ -52,6 +53,7 @@ func defaultStreamMiddleWares() []grpc.StreamServerInterceptor {
}
}
// Default middlewares for unary.
func defaultUnaryMiddleWares() []grpc.UnaryServerInterceptor {
return []grpc.UnaryServerInterceptor{
grpc_validator.UnaryServerInterceptor(),
@ -61,14 +63,21 @@ func defaultUnaryMiddleWares() []grpc.UnaryServerInterceptor {
}
}
// Server is grpc server.
type Server struct {
db *gorm.DB
rdb *redis.Client
cache *cache.Cache
// GORM instance.
db *gorm.DB
// Redis client instance.
rdb *redis.Client
// Cache instance.
cache *cache.Cache
// Searcher interface.
searcher searcher.Searcher
// Manager grpc interface.
manager.UnimplementedManagerServer
}
// New returns a new manager server from the given options.
func New(database *database.Database, cache *cache.Cache, searcher searcher.Searcher, opts ...grpc.ServerOption) *grpc.Server {
server := &Server{
db: database.DB,
@ -82,23 +91,186 @@ func New(database *database.Database, cache *cache.Cache, searcher searcher.Sear
grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(defaultUnaryMiddleWares()...)),
}, opts...)...)
// Register servers on grpc server
// Register servers on grpc server.
manager.RegisterManagerServer(grpcServer, server)
healthpb.RegisterHealthServer(grpcServer, health.NewServer())
return grpcServer
}
// Get SeedPeer and SeedPeer cluster configuration.
func (s *Server) GetSeedPeer(ctx context.Context, req *manager.GetSeedPeerRequest) (*manager.SeedPeer, error) {
var pbSeedPeer manager.SeedPeer
cacheKey := cache.MakeSeedPeerCacheKey(req.HostName, uint(req.SeedPeerClusterId))
// Cache hit.
if err := s.cache.Get(ctx, cacheKey, &pbSeedPeer); err == nil {
logger.Infof("%s cache hit", cacheKey)
return &pbSeedPeer, nil
}
// Cache miss.
logger.Infof("%s cache miss", cacheKey)
seedPeer := model.SeedPeer{}
if err := s.db.WithContext(ctx).Preload("SeedPeerCluster").Preload("SeedPeerCluster.SchedulerClusters.Schedulers", &model.Scheduler{
State: model.SchedulerStateActive,
}).First(&seedPeer, &model.SeedPeer{
HostName: req.HostName,
SeedPeerClusterID: uint(req.SeedPeerClusterId),
}).Error; err != nil {
return nil, status.Error(codes.Unknown, err.Error())
}
// Marshal config of seed peer cluster.
config, err := seedPeer.SeedPeerCluster.Config.MarshalJSON()
if err != nil {
return nil, status.Error(codes.DataLoss, err.Error())
}
// Construct schedulers.
var pbSchedulers []*manager.Scheduler
for _, schedulerCluster := range seedPeer.SeedPeerCluster.SchedulerClusters {
for _, scheduler := range schedulerCluster.Schedulers {
pbSchedulers = append(pbSchedulers, &manager.Scheduler{
Id: uint64(scheduler.ID),
HostName: scheduler.HostName,
Idc: scheduler.IDC,
NetTopology: scheduler.NetTopology,
Location: scheduler.Location,
Ip: scheduler.IP,
Port: scheduler.Port,
State: scheduler.State,
})
}
}
// Construct seed peer.
pbSeedPeer = manager.SeedPeer{
Id: uint64(seedPeer.ID),
Type: seedPeer.Type,
HostName: seedPeer.HostName,
Idc: seedPeer.IDC,
NetTopology: seedPeer.NetTopology,
Location: seedPeer.Location,
Ip: seedPeer.IP,
Port: seedPeer.Port,
DownloadPort: seedPeer.DownloadPort,
State: seedPeer.State,
SeedPeerClusterId: uint64(seedPeer.SeedPeerClusterID),
SeedPeerCluster: &manager.SeedPeerCluster{
Id: uint64(seedPeer.SeedPeerCluster.ID),
Name: seedPeer.SeedPeerCluster.Name,
Bio: seedPeer.SeedPeerCluster.BIO,
Config: config,
},
Schedulers: pbSchedulers,
}
// Cache data.
if err := s.cache.Once(&cachev8.Item{
Ctx: ctx,
Key: cacheKey,
Value: &pbSeedPeer,
TTL: s.cache.TTL,
}); err != nil {
logger.Warnf("storage cache failed: %v", err)
}
return &pbSeedPeer, nil
}
// Update SeedPeer configuration.
func (s *Server) UpdateSeedPeer(ctx context.Context, req *manager.UpdateSeedPeerRequest) (*manager.SeedPeer, error) {
seedPeer := model.SeedPeer{}
if err := s.db.WithContext(ctx).First(&seedPeer, model.SeedPeer{
HostName: req.HostName,
SeedPeerClusterID: uint(req.SeedPeerClusterId),
}).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return s.createSeedPeer(ctx, req)
}
return nil, status.Error(codes.Unknown, err.Error())
}
if err := s.db.WithContext(ctx).Model(&seedPeer).Updates(model.SeedPeer{
Type: req.Type,
IDC: req.Idc,
NetTopology: req.NetTopology,
Location: req.Location,
IP: req.Ip,
Port: req.Port,
DownloadPort: req.DownloadPort,
SeedPeerClusterID: uint(req.SeedPeerClusterId),
}).Error; err != nil {
return nil, status.Error(codes.Unknown, err.Error())
}
if err := s.cache.Delete(
ctx,
cache.MakeSeedPeerCacheKey(seedPeer.HostName, seedPeer.SeedPeerClusterID),
); err != nil {
logger.Warnf("%s refresh keepalive status failed in seed peer cluster %d", seedPeer.HostName, seedPeer.SeedPeerClusterID)
}
return &manager.SeedPeer{
Id: uint64(seedPeer.ID),
HostName: seedPeer.HostName,
Type: seedPeer.Type,
Idc: seedPeer.IDC,
NetTopology: seedPeer.NetTopology,
Location: seedPeer.Location,
Ip: seedPeer.IP,
Port: seedPeer.Port,
DownloadPort: seedPeer.DownloadPort,
State: seedPeer.State,
SeedPeerClusterId: uint64(seedPeer.SeedPeerClusterID),
}, nil
}
// Create SeedPeer and associate cluster.
func (s *Server) createSeedPeer(ctx context.Context, req *manager.UpdateSeedPeerRequest) (*manager.SeedPeer, error) {
seedPeer := model.SeedPeer{
HostName: req.HostName,
Type: req.Type,
IDC: req.Idc,
NetTopology: req.NetTopology,
Location: req.Location,
IP: req.Ip,
Port: req.Port,
DownloadPort: req.DownloadPort,
SeedPeerClusterID: uint(req.SeedPeerClusterId),
}
if err := s.db.WithContext(ctx).Create(&seedPeer).Error; err != nil {
return nil, status.Error(codes.Unknown, err.Error())
}
return &manager.SeedPeer{
Id: uint64(seedPeer.ID),
HostName: seedPeer.HostName,
Type: seedPeer.Type,
Idc: seedPeer.IDC,
NetTopology: seedPeer.NetTopology,
Location: seedPeer.Location,
Ip: seedPeer.IP,
Port: seedPeer.Port,
DownloadPort: seedPeer.DownloadPort,
SeedPeerClusterId: uint64(seedPeer.SeedPeerClusterID),
State: seedPeer.State,
}, nil
}
// Deprecated: Use GetSeedPeer instead.
func (s *Server) GetCDN(ctx context.Context, req *manager.GetCDNRequest) (*manager.CDN, error) {
var pbCDN manager.CDN
cacheKey := cache.MakeCDNCacheKey(req.HostName, uint(req.CdnClusterId))
// Cache Hit
// Cache hit.
if err := s.cache.Get(ctx, cacheKey, &pbCDN); err == nil {
logger.Infof("%s cache hit", cacheKey)
return &pbCDN, nil
}
// Cache Miss
// Cache miss.
logger.Infof("%s cache miss", cacheKey)
cdn := model.CDN{}
if err := s.db.WithContext(ctx).Preload("CDNCluster").Preload("CDNCluster.SchedulerClusters.Schedulers", &model.Scheduler{
@ -110,11 +282,13 @@ func (s *Server) GetCDN(ctx context.Context, req *manager.GetCDNRequest) (*manag
return nil, status.Error(codes.Unknown, err.Error())
}
// Marshal config of cdn cluster.
config, err := cdn.CDNCluster.Config.MarshalJSON()
if err != nil {
return nil, status.Error(codes.DataLoss, err.Error())
}
// Construct schedulers.
var pbSchedulers []*manager.Scheduler
for _, schedulerCluster := range cdn.CDNCluster.SchedulerClusters {
for _, scheduler := range schedulerCluster.Schedulers {
@ -130,6 +304,7 @@ func (s *Server) GetCDN(ctx context.Context, req *manager.GetCDNRequest) (*manag
}
}
// Construct cdn.
pbCDN = manager.CDN{
Id: uint64(cdn.ID),
HostName: cdn.HostName,
@ -149,6 +324,7 @@ func (s *Server) GetCDN(ctx context.Context, req *manager.GetCDNRequest) (*manag
Schedulers: pbSchedulers,
}
// Cache data.
if err := s.cache.Once(&cachev8.Item{
Ctx: ctx,
Key: cacheKey,
@ -161,6 +337,7 @@ func (s *Server) GetCDN(ctx context.Context, req *manager.GetCDNRequest) (*manag
return &pbCDN, nil
}
// Deprecated: Use UpdateSeedPeer instead.
func (s *Server) UpdateCDN(ctx context.Context, req *manager.UpdateCDNRequest) (*manager.CDN, error) {
cdn := model.CDN{}
if err := s.db.WithContext(ctx).First(&cdn, model.CDN{
@ -194,6 +371,7 @@ func (s *Server) UpdateCDN(ctx context.Context, req *manager.UpdateCDNRequest) (
return &manager.CDN{
Id: uint64(cdn.ID),
HostName: cdn.HostName,
Idc: cdn.IDC,
Location: cdn.Location,
Ip: cdn.IP,
Port: cdn.Port,
@ -203,6 +381,7 @@ func (s *Server) UpdateCDN(ctx context.Context, req *manager.UpdateCDNRequest) (
}, nil
}
// Deprecated: Use createSeedPeer instead.
func (s *Server) createCDN(ctx context.Context, req *manager.UpdateCDNRequest) (*manager.CDN, error) {
cdn := model.CDN{
HostName: req.HostName,
@ -221,6 +400,7 @@ func (s *Server) createCDN(ctx context.Context, req *manager.UpdateCDNRequest) (
return &manager.CDN{
Id: uint64(cdn.ID),
HostName: cdn.HostName,
Idc: cdn.IDC,
Location: cdn.Location,
Ip: cdn.IP,
Port: cdn.Port,
@ -230,21 +410,24 @@ func (s *Server) createCDN(ctx context.Context, req *manager.UpdateCDNRequest) (
}, nil
}
// Get Scheduler and Scheduler cluster configuration.
func (s *Server) GetScheduler(ctx context.Context, req *manager.GetSchedulerRequest) (*manager.Scheduler, error) {
var pbScheduler manager.Scheduler
cacheKey := cache.MakeSchedulerCacheKey(req.HostName, uint(req.SchedulerClusterId))
// Cache Hit
// Cache hit.
if err := s.cache.Get(ctx, cacheKey, &pbScheduler); err == nil {
logger.Infof("%s cache hit", cacheKey)
return &pbScheduler, nil
}
// Cache Miss
// Cache miss.
logger.Infof("%s cache miss", cacheKey)
scheduler := model.Scheduler{}
if err := s.db.WithContext(ctx).Preload("SchedulerCluster").Preload("SchedulerCluster.CDNClusters.CDNs", &model.CDN{
State: model.CDNStateActive,
}).Preload("SchedulerCluster.SeedPeerClusters.SeedPeers", &model.CDN{
State: model.SeedPeerStateActive,
}).First(&scheduler, &model.Scheduler{
HostName: req.HostName,
SchedulerClusterID: uint(req.SchedulerClusterId),
@ -252,21 +435,50 @@ func (s *Server) GetScheduler(ctx context.Context, req *manager.GetSchedulerRequ
return nil, status.Error(codes.Unknown, err.Error())
}
schedulerNetConfig, err := scheduler.NetConfig.MarshalJSON()
if err != nil {
return nil, status.Error(codes.DataLoss, err.Error())
}
// Marshal config of scheduler.
schedulerClusterConfig, err := scheduler.SchedulerCluster.Config.MarshalJSON()
if err != nil {
return nil, status.Error(codes.DataLoss, err.Error())
}
// Marshal config of client.
schedulerClusterClientConfig, err := scheduler.SchedulerCluster.ClientConfig.MarshalJSON()
if err != nil {
return nil, status.Error(codes.DataLoss, err.Error())
}
// Construct seed peers.
var pbSeedPeers []*manager.SeedPeer
for _, seedPeerCluster := range scheduler.SchedulerCluster.SeedPeerClusters {
seedPeerClusterConfig, err := seedPeerCluster.Config.MarshalJSON()
if err != nil {
return nil, status.Error(codes.DataLoss, err.Error())
}
for _, seedPeer := range seedPeerCluster.SeedPeers {
pbSeedPeers = append(pbSeedPeers, &manager.SeedPeer{
Id: uint64(seedPeer.ID),
HostName: seedPeer.HostName,
Type: seedPeer.Type,
Idc: seedPeer.IDC,
NetTopology: seedPeer.NetTopology,
Location: seedPeer.Location,
Ip: seedPeer.IP,
Port: seedPeer.Port,
DownloadPort: seedPeer.DownloadPort,
State: seedPeer.State,
SeedPeerClusterId: uint64(seedPeer.SeedPeerClusterID),
SeedPeerCluster: &manager.SeedPeerCluster{
Id: uint64(seedPeerCluster.ID),
Name: seedPeerCluster.Name,
Bio: seedPeerCluster.BIO,
Config: seedPeerClusterConfig,
},
})
}
}
// Deprecated: Use pbSeedPeers instead.
var pbCDNs []*manager.CDN
for _, cdnCluster := range scheduler.SchedulerCluster.CDNClusters {
cdnClusterConfig, err := cdnCluster.Config.MarshalJSON()
@ -283,6 +495,7 @@ func (s *Server) GetScheduler(ctx context.Context, req *manager.GetSchedulerRequ
Ip: cdn.IP,
Port: cdn.Port,
DownloadPort: cdn.DownloadPort,
State: cdn.State,
CdnClusterId: uint64(cdn.CDNClusterID),
CdnCluster: &manager.CDNCluster{
Id: uint64(cdnCluster.ID),
@ -290,18 +503,17 @@ func (s *Server) GetScheduler(ctx context.Context, req *manager.GetSchedulerRequ
Bio: cdnCluster.BIO,
Config: cdnClusterConfig,
},
State: cdn.State,
})
}
}
// Construct scheduler.
pbScheduler = manager.Scheduler{
Id: uint64(scheduler.ID),
HostName: scheduler.HostName,
Vips: scheduler.VIPs,
Idc: scheduler.IDC,
NetTopology: scheduler.NetTopology,
Location: scheduler.Location,
NetConfig: schedulerNetConfig,
Ip: scheduler.IP,
Port: scheduler.Port,
State: scheduler.State,
@ -313,9 +525,11 @@ func (s *Server) GetScheduler(ctx context.Context, req *manager.GetSchedulerRequ
Config: schedulerClusterConfig,
ClientConfig: schedulerClusterClientConfig,
},
Cdns: pbCDNs,
SeedPeers: pbSeedPeers,
Cdns: pbCDNs,
}
// Cache data.
if err := s.cache.Once(&cachev8.Item{
Ctx: ctx,
Key: cacheKey,
@ -328,6 +542,7 @@ func (s *Server) GetScheduler(ctx context.Context, req *manager.GetSchedulerRequ
return &pbScheduler, nil
}
// Update scheduler configuration.
func (s *Server) UpdateScheduler(ctx context.Context, req *manager.UpdateSchedulerRequest) (*manager.Scheduler, error) {
scheduler := model.Scheduler{}
if err := s.db.WithContext(ctx).First(&scheduler, model.Scheduler{
@ -340,18 +555,10 @@ func (s *Server) UpdateScheduler(ctx context.Context, req *manager.UpdateSchedul
return nil, status.Error(codes.Unknown, err.Error())
}
var netConfig model.JSONMap
if len(req.NetConfig) > 0 {
if err := netConfig.UnmarshalJSON(req.NetConfig); err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
}
}
if err := s.db.WithContext(ctx).Model(&scheduler).Updates(model.Scheduler{
VIPs: req.Vips,
IDC: req.Idc,
NetTopology: req.NetTopology,
Location: req.Location,
NetConfig: netConfig,
IP: req.Ip,
Port: req.Port,
SchedulerClusterID: uint(req.SchedulerClusterId),
@ -369,10 +576,9 @@ func (s *Server) UpdateScheduler(ctx context.Context, req *manager.UpdateSchedul
return &manager.Scheduler{
Id: uint64(scheduler.ID),
HostName: scheduler.HostName,
Vips: scheduler.VIPs,
Idc: scheduler.IDC,
NetTopology: scheduler.NetTopology,
Location: scheduler.Location,
NetConfig: req.NetConfig,
Ip: scheduler.IP,
Port: scheduler.Port,
SchedulerClusterId: uint64(scheduler.SchedulerClusterID),
@ -380,20 +586,13 @@ func (s *Server) UpdateScheduler(ctx context.Context, req *manager.UpdateSchedul
}, nil
}
// Create scheduler and associate cluster.
func (s *Server) createScheduler(ctx context.Context, req *manager.UpdateSchedulerRequest) (*manager.Scheduler, error) {
var netConfig model.JSONMap
if len(req.NetConfig) > 0 {
if err := netConfig.UnmarshalJSON(req.NetConfig); err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
}
}
scheduler := model.Scheduler{
HostName: req.HostName,
VIPs: req.Vips,
IDC: req.Idc,
NetTopology: req.NetTopology,
Location: req.Location,
NetConfig: netConfig,
IP: req.Ip,
Port: req.Port,
SchedulerClusterID: uint(req.SchedulerClusterId),
@ -406,10 +605,9 @@ func (s *Server) createScheduler(ctx context.Context, req *manager.UpdateSchedul
return &manager.Scheduler{
Id: uint64(scheduler.ID),
HostName: scheduler.HostName,
Vips: scheduler.VIPs,
Idc: scheduler.IDC,
NetTopology: scheduler.NetTopology,
Location: scheduler.Location,
NetConfig: req.NetConfig,
Ip: scheduler.IP,
Port: scheduler.Port,
State: scheduler.State,
@ -417,26 +615,27 @@ func (s *Server) createScheduler(ctx context.Context, req *manager.UpdateSchedul
}, nil
}
// List acitve schedulers configuration.
func (s *Server) ListSchedulers(ctx context.Context, req *manager.ListSchedulersRequest) (*manager.ListSchedulersResponse, error) {
log := logger.WithHostnameAndIP(req.HostName, req.Ip)
var pbListSchedulersResponse manager.ListSchedulersResponse
cacheKey := cache.MakeSchedulersCacheKey(req.HostName, req.Ip)
// Cache Hit
// Cache hit.
if err := s.cache.Get(ctx, cacheKey, &pbListSchedulersResponse); err == nil {
log.Infof("%s cache hit", cacheKey)
return &pbListSchedulersResponse, nil
}
// Cache Miss
// Cache miss.
log.Infof("%s cache miss", cacheKey)
var schedulerClusters []model.SchedulerCluster
if err := s.db.WithContext(ctx).Preload("SecurityGroup.SecurityRules").Preload("Schedulers", "state = ?", "active").Find(&schedulerClusters).Error; err != nil {
return nil, status.Error(codes.Unknown, err.Error())
}
// Search optimal scheduler clusters
// Search optimal scheduler clusters.
log.Infof("list scheduler clusters %v with hostInfo %#v", getSchedulerClusterNames(schedulerClusters), req.HostInfo)
schedulerClusters, err := s.searcher.FindSchedulerClusters(ctx, schedulerClusters, req)
if err != nil {
@ -452,26 +651,22 @@ func (s *Server) ListSchedulers(ctx context.Context, req *manager.ListSchedulers
}
}
// Construct schedulers.
for _, scheduler := range schedulers {
schedulerNetConfig, err := scheduler.NetConfig.MarshalJSON()
if err != nil {
return nil, status.Error(codes.DataLoss, err.Error())
}
pbListSchedulersResponse.Schedulers = append(pbListSchedulersResponse.Schedulers, &manager.Scheduler{
Id: uint64(scheduler.ID),
HostName: scheduler.HostName,
Vips: scheduler.VIPs,
Idc: scheduler.IDC,
NetTopology: scheduler.NetTopology,
Location: scheduler.Location,
NetConfig: schedulerNetConfig,
Ip: scheduler.IP,
Port: scheduler.Port,
SchedulerClusterId: uint64(scheduler.SchedulerClusterID),
State: scheduler.State,
SchedulerClusterId: uint64(scheduler.SchedulerClusterID),
})
}
// Cache data.
if err := s.cache.Once(&cachev8.Item{
Ctx: ctx,
Key: cacheKey,
@ -484,6 +679,7 @@ func (s *Server) ListSchedulers(ctx context.Context, req *manager.ListSchedulers
return &pbListSchedulersResponse, nil
}
// KeepAlive with manager.
func (s *Server) KeepAlive(stream manager.Manager_KeepAliveServer) error {
req, err := stream.Recv()
if err != nil {
@ -495,7 +691,7 @@ func (s *Server) KeepAlive(stream manager.Manager_KeepAliveServer) error {
clusterID := uint(req.ClusterId)
logger.Infof("%s keepalive successfully for the first time in cluster %d", hostName, clusterID)
// Active scheduler
// Active scheduler.
if sourceType == manager.SourceType_SCHEDULER_SOURCE {
scheduler := model.Scheduler{}
if err := s.db.First(&scheduler, model.Scheduler{
@ -515,7 +711,27 @@ func (s *Server) KeepAlive(stream manager.Manager_KeepAliveServer) error {
}
}
// Active CDN
// Active seed peer.
if sourceType == manager.SourceType_SEED_PEER_SOURCE {
seedPeer := model.SeedPeer{}
if err := s.db.First(&seedPeer, model.SeedPeer{
HostName: hostName,
SeedPeerClusterID: clusterID,
}).Updates(model.SeedPeer{
State: model.SeedPeerStateActive,
}).Error; err != nil {
return status.Error(codes.Unknown, err.Error())
}
if err := s.cache.Delete(
context.TODO(),
cache.MakeSeedPeerCacheKey(hostName, clusterID),
); err != nil {
logger.Warnf("%s refresh keepalive status failed in seed peer cluster %d", hostName, clusterID)
}
}
// Deprecated: Use SourceType_SEED_PEER_SOURCE instead.
if sourceType == manager.SourceType_CDN_SOURCE {
cdn := model.CDN{}
if err := s.db.First(&cdn, model.CDN{
@ -538,7 +754,7 @@ func (s *Server) KeepAlive(stream manager.Manager_KeepAliveServer) error {
for {
_, err := stream.Recv()
if err != nil {
// Inactive scheduler
// Inactive scheduler.
if sourceType == manager.SourceType_SCHEDULER_SOURCE {
scheduler := model.Scheduler{}
if err := s.db.First(&scheduler, model.Scheduler{
@ -558,7 +774,27 @@ func (s *Server) KeepAlive(stream manager.Manager_KeepAliveServer) error {
}
}
// Inactive CDN
// Inactive seed peer.
if sourceType == manager.SourceType_SEED_PEER_SOURCE {
seedPeer := model.SeedPeer{}
if err := s.db.First(&seedPeer, model.SeedPeer{
HostName: hostName,
SeedPeerClusterID: clusterID,
}).Updates(model.SeedPeer{
State: model.SeedPeerStateInactive,
}).Error; err != nil {
return status.Error(codes.Unknown, err.Error())
}
if err := s.cache.Delete(
context.TODO(),
cache.MakeSeedPeerCacheKey(hostName, clusterID),
); err != nil {
logger.Warnf("%s refresh keepalive status failed in seed peer cluster %d", hostName, clusterID)
}
}
// Deprecated: Use SourceType_SEED_PEER_SOURCE instead.
if sourceType == manager.SourceType_CDN_SOURCE {
cdn := model.CDN{}
if err := s.db.First(&cdn, model.CDN{
@ -591,6 +827,7 @@ func (s *Server) KeepAlive(stream manager.Manager_KeepAliveServer) error {
}
}
// Get scheduler cluster names.
func getSchedulerClusterNames(clusters []model.SchedulerCluster) []string {
names := []string{}
for _, cluster := range clusters {

View File

@ -33,7 +33,7 @@ func (s *service) CreateApplication(ctx context.Context, json types.CreateApplic
State: json.State,
}
if err := s.db.WithContext(ctx).Preload("CDNClusters").Preload("SchedulerClusters").Preload("User").Create(&application).Error; err != nil {
if err := s.db.WithContext(ctx).Preload("SeedPeerClusters").Preload("CDNClusters").Preload("SchedulerClusters").Preload("User").Create(&application).Error; err != nil {
return nil, err
}
@ -55,7 +55,7 @@ func (s *service) DestroyApplication(ctx context.Context, id uint) error {
func (s *service) UpdateApplication(ctx context.Context, id uint, json types.UpdateApplicationRequest) (*model.Application, error) {
application := model.Application{}
if err := s.db.WithContext(ctx).Preload("CDNClusters").Preload("SchedulerClusters").Preload("User").First(&application, id).Updates(model.Application{
if err := s.db.WithContext(ctx).Preload("SeedPeerClusters").Preload("CDNClusters").Preload("SchedulerClusters").Preload("User").First(&application, id).Updates(model.Application{
Name: json.Name,
DownloadRateLimit: json.DownloadRateLimit,
URL: json.URL,
@ -71,7 +71,7 @@ func (s *service) UpdateApplication(ctx context.Context, id uint, json types.Upd
func (s *service) GetApplication(ctx context.Context, id uint) (*model.Application, error) {
application := model.Application{}
if err := s.db.WithContext(ctx).Preload("CDNClusters").Preload("SchedulerClusters").Preload("User").First(&application, id).Error; err != nil {
if err := s.db.WithContext(ctx).Preload("SeedPeerClusters").Preload("CDNClusters").Preload("SchedulerClusters").Preload("User").First(&application, id).Error; err != nil {
return nil, err
}
@ -81,7 +81,7 @@ func (s *service) GetApplication(ctx context.Context, id uint) (*model.Applicati
func (s *service) GetApplications(ctx context.Context, q types.GetApplicationsQuery) (*[]model.Application, int64, error) {
var count int64
applications := []model.Application{}
if err := s.db.WithContext(ctx).Scopes(model.Paginate(q.Page, q.PerPage)).Preload("CDNClusters").Preload("SchedulerClusters").Preload("User").Find(&applications).Count(&count).Error; err != nil {
if err := s.db.WithContext(ctx).Scopes(model.Paginate(q.Page, q.PerPage)).Preload("SeedPeerClusters").Preload("CDNClusters").Preload("SchedulerClusters").Preload("User").Find(&applications).Count(&count).Error; err != nil {
return nil, 0, err
}
@ -124,6 +124,42 @@ func (s *service) DeleteSchedulerClusterToApplication(ctx context.Context, id, s
return nil
}
func (s *service) AddSeedPeerClusterToApplication(ctx context.Context, id, seedPeerClusterID uint) error {
application := model.Application{}
if err := s.db.WithContext(ctx).First(&application, id).Error; err != nil {
return err
}
seedPeerCluster := model.SeedPeerCluster{}
if err := s.db.WithContext(ctx).First(&seedPeerCluster, seedPeerClusterID).Error; err != nil {
return err
}
if err := s.db.WithContext(ctx).Model(&application).Association("SeedPeerClusters").Append(&seedPeerCluster); err != nil {
return err
}
return nil
}
func (s *service) DeleteSeedPeerClusterToApplication(ctx context.Context, id, seedPeerClusterID uint) error {
application := model.Application{}
if err := s.db.WithContext(ctx).First(&application, id).Error; err != nil {
return err
}
seedPeerCluster := model.SeedPeerCluster{}
if err := s.db.WithContext(ctx).First(&seedPeerCluster, seedPeerClusterID).Error; err != nil {
return err
}
if err := s.db.Model(&application).Association("SeedPeerClusters").Delete(&seedPeerCluster); err != nil {
return err
}
return nil
}
func (s *service) AddCDNClusterToApplication(ctx context.Context, id, cdnClusterID uint) error {
application := model.Application{}
if err := s.db.WithContext(ctx).First(&application, id).Error; err != nil {

View File

@ -155,7 +155,7 @@ func (s *service) DestroyJob(ctx context.Context, id uint) error {
func (s *service) UpdateJob(ctx context.Context, id uint, json types.UpdateJobRequest) (*model.Job, error) {
job := model.Job{}
if err := s.db.WithContext(ctx).Preload("CDNClusters").Preload("SchedulerClusters").First(&job, id).Updates(model.Job{
if err := s.db.WithContext(ctx).Preload("SeedPeerClusters").Preload("CDNClusters").Preload("SchedulerClusters").First(&job, id).Updates(model.Job{
BIO: json.BIO,
UserID: json.UserID,
}).Error; err != nil {
@ -167,7 +167,7 @@ func (s *service) UpdateJob(ctx context.Context, id uint, json types.UpdateJobRe
func (s *service) GetJob(ctx context.Context, id uint) (*model.Job, error) {
job := model.Job{}
if err := s.db.WithContext(ctx).Preload("CDNClusters").Preload("SchedulerClusters").First(&job, id).Error; err != nil {
if err := s.db.WithContext(ctx).Preload("SeedPeerClusters").Preload("SchedulerClusters").First(&job, id).Error; err != nil {
return nil, err
}
@ -210,6 +210,28 @@ func (s *service) AddJobToSchedulerClusters(ctx context.Context, id, schedulerCl
return nil
}
func (s *service) AddJobToSeedPeerClusters(ctx context.Context, id, seedPeerClusterIDs []uint) error {
job := model.Job{}
if err := s.db.WithContext(ctx).First(&job, id).Error; err != nil {
return err
}
var seedPeerClusters []*model.SeedPeerCluster
for _, seedPeerClusterID := range seedPeerClusterIDs {
seedPeerCluster := model.SeedPeerCluster{}
if err := s.db.WithContext(ctx).First(&seedPeerCluster, seedPeerClusterID).Error; err != nil {
return err
}
seedPeerClusters = append(seedPeerClusters, &seedPeerCluster)
}
if err := s.db.WithContext(ctx).Model(&job).Association("SeedPeerClusters").Append(seedPeerClusters); err != nil {
return err
}
return nil
}
func (s *service) AddJobToCDNClusters(ctx context.Context, id, cdnClusterIDs []uint) error {
job := model.Job{}
if err := s.db.WithContext(ctx).First(&job, id).Error; err != nil {

View File

@ -26,10 +26,9 @@ import (
func (s *service) CreateScheduler(ctx context.Context, json types.CreateSchedulerRequest) (*model.Scheduler, error) {
scheduler := model.Scheduler{
HostName: json.HostName,
VIPs: json.VIPs,
IDC: json.IDC,
NetTopology: json.NetTopology,
Location: json.Location,
NetConfig: json.NetConfig,
IP: json.IP,
Port: json.Port,
SchedulerClusterID: json.SchedulerClusterID,
@ -58,10 +57,9 @@ func (s *service) DestroyScheduler(ctx context.Context, id uint) error {
func (s *service) UpdateScheduler(ctx context.Context, id uint, json types.UpdateSchedulerRequest) (*model.Scheduler, error) {
scheduler := model.Scheduler{}
if err := s.db.WithContext(ctx).First(&scheduler, id).Updates(model.Scheduler{
VIPs: json.VIPs,
IDC: json.IDC,
NetTopology: json.NetTopology,
Location: json.Location,
NetConfig: json.NetConfig,
IP: json.IP,
Port: json.Port,
SchedulerClusterID: json.SchedulerClusterID,

View File

@ -54,6 +54,12 @@ func (s *service) CreateSchedulerCluster(ctx context.Context, json types.CreateS
return nil, err
}
if json.SeedPeerClusterID > 0 {
if err := s.AddSchedulerClusterToSeedPeerCluster(ctx, json.SeedPeerClusterID, schedulerCluster.ID); err != nil {
return nil, err
}
}
if json.CDNClusterID > 0 {
if err := s.AddSchedulerClusterToCDNCluster(ctx, json.CDNClusterID, schedulerCluster.ID); err != nil {
return nil, err
@ -108,6 +114,12 @@ func (s *service) UpdateSchedulerCluster(ctx context.Context, id uint, json type
return nil, err
}
if json.SeedPeerClusterID > 0 {
if err := s.AddSchedulerClusterToSeedPeerCluster(ctx, json.SeedPeerClusterID, schedulerCluster.ID); err != nil {
return nil, err
}
}
if json.CDNClusterID > 0 {
if err := s.AddSchedulerClusterToCDNCluster(ctx, json.CDNClusterID, schedulerCluster.ID); err != nil {
return nil, err
@ -119,7 +131,7 @@ func (s *service) UpdateSchedulerCluster(ctx context.Context, id uint, json type
func (s *service) GetSchedulerCluster(ctx context.Context, id uint) (*model.SchedulerCluster, error) {
schedulerCluster := model.SchedulerCluster{}
if err := s.db.WithContext(ctx).Preload("CDNClusters").First(&schedulerCluster, id).Error; err != nil {
if err := s.db.WithContext(ctx).Preload("SeedPeerClusters").Preload("CDNClusters").First(&schedulerCluster, id).Error; err != nil {
return nil, err
}
@ -131,7 +143,7 @@ func (s *service) GetSchedulerClusters(ctx context.Context, q types.GetScheduler
var schedulerClusters []model.SchedulerCluster
if err := s.db.WithContext(ctx).Scopes(model.Paginate(q.Page, q.PerPage)).Where(&model.SchedulerCluster{
Name: q.Name,
}).Preload("CDNClusters").Find(&schedulerClusters).Count(&count).Error; err != nil {
}).Preload("SeedPeerClusters").Preload("CDNClusters").Find(&schedulerClusters).Count(&count).Error; err != nil {
return nil, 0, err
}

View File

@ -100,6 +100,24 @@ func (s *service) AddSchedulerClusterToSecurityGroup(ctx context.Context, id, sc
return nil
}
func (s *service) AddSeedPeerClusterToSecurityGroup(ctx context.Context, id, seedPeerClusterID uint) error {
securityGroup := model.SecurityGroup{}
if err := s.db.WithContext(ctx).First(&securityGroup, id).Error; err != nil {
return err
}
seedPeerCluster := model.SeedPeerCluster{}
if err := s.db.WithContext(ctx).First(&seedPeerCluster, seedPeerClusterID).Error; err != nil {
return err
}
if err := s.db.WithContext(ctx).Model(&securityGroup).Association("SeedPeerClusters").Append(&seedPeerCluster); err != nil {
return err
}
return nil
}
func (s *service) AddCDNClusterToSecurityGroup(ctx context.Context, id, cdnClusterID uint) error {
securityGroup := model.SecurityGroup{}
if err := s.db.WithContext(ctx).First(&securityGroup, id).Error; err != nil {

View File

@ -0,0 +1,103 @@
/*
* Copyright 2022 The Dragonfly 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 service
import (
"context"
"d7y.io/dragonfly/v2/manager/model"
"d7y.io/dragonfly/v2/manager/types"
)
func (s *service) CreateSeedPeer(ctx context.Context, json types.CreateSeedPeerRequest) (*model.SeedPeer, error) {
seedPeer := model.SeedPeer{
HostName: json.HostName,
Type: json.Type,
IDC: json.IDC,
NetTopology: json.NetTopology,
Location: json.Location,
IP: json.IP,
Port: json.Port,
DownloadPort: json.DownloadPort,
SeedPeerClusterID: json.SeedPeerClusterID,
}
if err := s.db.WithContext(ctx).Create(&seedPeer).Error; err != nil {
return nil, err
}
return &seedPeer, nil
}
func (s *service) DestroySeedPeer(ctx context.Context, id uint) error {
seedPeer := model.SeedPeer{}
if err := s.db.WithContext(ctx).First(&seedPeer, id).Error; err != nil {
return err
}
if err := s.db.WithContext(ctx).Unscoped().Delete(&model.SeedPeer{}, id).Error; err != nil {
return err
}
return nil
}
func (s *service) UpdateSeedPeer(ctx context.Context, id uint, json types.UpdateSeedPeerRequest) (*model.SeedPeer, error) {
seedPeer := model.SeedPeer{}
if err := s.db.WithContext(ctx).First(&seedPeer, id).Updates(model.SeedPeer{
Type: json.Type,
IDC: json.IDC,
NetTopology: json.NetTopology,
Location: json.Location,
IP: json.IP,
Port: json.Port,
DownloadPort: json.DownloadPort,
SeedPeerClusterID: json.SeedPeerClusterID,
}).Error; err != nil {
return nil, err
}
return &seedPeer, nil
}
func (s *service) GetSeedPeer(ctx context.Context, id uint) (*model.SeedPeer, error) {
seedPeer := model.SeedPeer{}
if err := s.db.WithContext(ctx).First(&seedPeer, id).Error; err != nil {
return nil, err
}
return &seedPeer, nil
}
func (s *service) GetSeedPeers(ctx context.Context, q types.GetSeedPeersQuery) (*[]model.SeedPeer, int64, error) {
var count int64
var seedPeers []model.SeedPeer
if err := s.db.WithContext(ctx).Scopes(model.Paginate(q.Page, q.PerPage)).Where(&model.SeedPeer{
Type: q.Type,
HostName: q.HostName,
IDC: q.IDC,
Location: q.Location,
IP: q.IP,
Port: q.Port,
DownloadPort: q.DownloadPort,
SeedPeerClusterID: q.SeedPeerClusterID,
}).Find(&seedPeers).Count(&count).Error; err != nil {
return nil, 0, err
}
return &seedPeers, count, nil
}

View File

@ -0,0 +1,160 @@
/*
* Copyright 2022 The Dragonfly 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 service
import (
"context"
"errors"
"d7y.io/dragonfly/v2/manager/model"
"d7y.io/dragonfly/v2/manager/types"
"d7y.io/dragonfly/v2/pkg/util/structutils"
)
func (s *service) CreateSeedPeerCluster(ctx context.Context, json types.CreateSeedPeerClusterRequest) (*model.SeedPeerCluster, error) {
config, err := structutils.StructToMap(json.Config)
if err != nil {
return nil, err
}
scopes, err := structutils.StructToMap(json.Scopes)
if err != nil {
return nil, err
}
seedPeerCluster := model.SeedPeerCluster{
Name: json.Name,
BIO: json.BIO,
Config: config,
Scopes: scopes,
IsDefault: json.IsDefault,
}
if err := s.db.WithContext(ctx).Create(&seedPeerCluster).Error; err != nil {
return nil, err
}
return &seedPeerCluster, nil
}
func (s *service) DestroySeedPeerCluster(ctx context.Context, id uint) error {
seedPeerCluster := model.SeedPeerCluster{}
if err := s.db.WithContext(ctx).Preload("SeedPeers").First(&seedPeerCluster, id).Error; err != nil {
return err
}
if len(seedPeerCluster.SeedPeers) != 0 {
return errors.New("seedPeer cluster exists seedPeer")
}
if err := s.db.WithContext(ctx).Unscoped().Delete(&model.SeedPeerCluster{}, id).Error; err != nil {
return err
}
return nil
}
func (s *service) UpdateSeedPeerCluster(ctx context.Context, id uint, json types.UpdateSeedPeerClusterRequest) (*model.SeedPeerCluster, error) {
config, err := structutils.StructToMap(json.Config)
if err != nil {
return nil, err
}
scopes, err := structutils.StructToMap(json.Scopes)
if err != nil {
return nil, err
}
seedPeerCluster := model.SeedPeerCluster{}
if err := s.db.WithContext(ctx).First(&seedPeerCluster, id).Updates(model.SeedPeerCluster{
Name: json.Name,
BIO: json.BIO,
Config: config,
Scopes: scopes,
IsDefault: json.IsDefault,
}).Error; err != nil {
return nil, err
}
return &seedPeerCluster, nil
}
func (s *service) GetSeedPeerCluster(ctx context.Context, id uint) (*model.SeedPeerCluster, error) {
seedPeerCluster := model.SeedPeerCluster{}
if err := s.db.WithContext(ctx).First(&seedPeerCluster, id).Error; err != nil {
return nil, err
}
return &seedPeerCluster, nil
}
func (s *service) GetSeedPeerClusters(ctx context.Context, q types.GetSeedPeerClustersQuery) (*[]model.SeedPeerCluster, int64, error) {
var count int64
var seedPeerClusters []model.SeedPeerCluster
if err := s.db.WithContext(ctx).Scopes(model.Paginate(q.Page, q.PerPage)).Where(&model.SeedPeerCluster{
Name: q.Name,
}).Find(&seedPeerClusters).Count(&count).Error; err != nil {
return nil, 0, err
}
return &seedPeerClusters, count, nil
}
func (s *service) AddSeedPeerToSeedPeerCluster(ctx context.Context, id, seedPeerID uint) error {
seedPeerCluster := model.SeedPeerCluster{}
if err := s.db.WithContext(ctx).First(&seedPeerCluster, id).Error; err != nil {
return err
}
seedPeer := model.SeedPeer{}
if err := s.db.WithContext(ctx).First(&seedPeer, seedPeerID).Error; err != nil {
return err
}
if err := s.db.WithContext(ctx).Model(&seedPeerCluster).Association("SeedPeers").Append(&seedPeer); err != nil {
return err
}
return nil
}
func (s *service) AddSchedulerClusterToSeedPeerCluster(ctx context.Context, id, schedulerClusterID uint) error {
seedPeerCluster := model.SeedPeerCluster{}
if err := s.db.WithContext(ctx).First(&seedPeerCluster, id).Error; err != nil {
return err
}
schedulerCluster := model.SchedulerCluster{}
if err := s.db.WithContext(ctx).First(&schedulerCluster, schedulerClusterID).Error; err != nil {
return err
}
seedPeerClusters := []model.SeedPeerCluster{}
if err := s.db.WithContext(ctx).Model(&schedulerCluster).Association("SeedPeerClusters").Find(&seedPeerClusters); err != nil {
return err
}
if err := s.db.WithContext(ctx).Model(&schedulerCluster).Association("SeedPeerClusters").Delete(seedPeerClusters); err != nil {
return err
}
if err := s.db.WithContext(ctx).Model(&seedPeerCluster).Association("SchedulerClusters").Append(&schedulerCluster); err != nil {
return err
}
return nil
}

View File

@ -60,6 +60,20 @@ type Service interface {
GetOauth(context.Context, uint) (*model.Oauth, error)
GetOauths(context.Context, types.GetOauthsQuery) (*[]model.Oauth, int64, error)
CreateSeedPeerCluster(context.Context, types.CreateSeedPeerClusterRequest) (*model.SeedPeerCluster, error)
DestroySeedPeerCluster(context.Context, uint) error
UpdateSeedPeerCluster(context.Context, uint, types.UpdateSeedPeerClusterRequest) (*model.SeedPeerCluster, error)
GetSeedPeerCluster(context.Context, uint) (*model.SeedPeerCluster, error)
GetSeedPeerClusters(context.Context, types.GetSeedPeerClustersQuery) (*[]model.SeedPeerCluster, int64, error)
AddSeedPeerToSeedPeerCluster(context.Context, uint, uint) error
AddSchedulerClusterToSeedPeerCluster(context.Context, uint, uint) error
CreateSeedPeer(context.Context, types.CreateSeedPeerRequest) (*model.SeedPeer, error)
DestroySeedPeer(context.Context, uint) error
UpdateSeedPeer(context.Context, uint, types.UpdateSeedPeerRequest) (*model.SeedPeer, error)
GetSeedPeer(context.Context, uint) (*model.SeedPeer, error)
GetSeedPeers(context.Context, types.GetSeedPeersQuery) (*[]model.SeedPeer, int64, error)
CreateCDNCluster(context.Context, types.CreateCDNClusterRequest) (*model.CDNCluster, error)
DestroyCDNCluster(context.Context, uint) error
UpdateCDNCluster(context.Context, uint, types.UpdateCDNClusterRequest) (*model.CDNCluster, error)
@ -99,6 +113,7 @@ type Service interface {
GetSecurityGroup(context.Context, uint) (*model.SecurityGroup, error)
GetSecurityGroups(context.Context, types.GetSecurityGroupsQuery) (*[]model.SecurityGroup, int64, error)
AddSchedulerClusterToSecurityGroup(context.Context, uint, uint) error
AddSeedPeerClusterToSecurityGroup(context.Context, uint, uint) error
AddCDNClusterToSecurityGroup(context.Context, uint, uint) error
AddSecurityRuleToSecurityGroup(context.Context, uint, uint) error
DestroySecurityRuleToSecurityGroup(context.Context, uint, uint) error
@ -125,6 +140,8 @@ type Service interface {
GetApplications(context.Context, types.GetApplicationsQuery) (*[]model.Application, int64, error)
AddSchedulerClusterToApplication(context.Context, uint, uint) error
DeleteSchedulerClusterToApplication(context.Context, uint, uint) error
AddSeedPeerClusterToApplication(context.Context, uint, uint) error
DeleteSeedPeerClusterToApplication(context.Context, uint, uint) error
AddCDNClusterToApplication(context.Context, uint, uint) error
DeleteCDNClusterToApplication(context.Context, uint, uint) error
}

View File

@ -30,6 +30,16 @@ type DeleteSchedulerClusterToApplicationParams struct {
SchedulerClusterID uint `uri:"scheduler_cluster_id" binding:"required"`
}
type AddSeedPeerClusterToApplicationParams struct {
ID uint `uri:"id" binding:"required"`
SeedPeerClusterID uint `uri:"seed_peer_cluster_id" binding:"required"`
}
type DeleteSeedPeerClusterToApplicationParams struct {
ID uint `uri:"id" binding:"required"`
SeedPeerClusterID uint `uri:"seed_peer_cluster_id" binding:"required"`
}
type AddCDNClusterToApplicationParams struct {
ID uint `uri:"id" binding:"required"`
CDNClusterID uint `uri:"cdn_cluster_id" binding:"required"`

View File

@ -22,7 +22,7 @@ type CDNParams struct {
type CreateCDNRequest struct {
HostName string `json:"host_name" binding:"required"`
IDC string `json:"idc" binding:"required"`
IDC string `json:"idc" binding:"omitempty"`
Location string `json:"location" binding:"omitempty"`
IP string `json:"ip" binding:"required"`
Port int32 `json:"port" binding:"required"`

View File

@ -22,6 +22,7 @@ type CreateJobRequest struct {
Args map[string]interface{} `json:"args" binding:"omitempty"`
Result map[string]interface{} `json:"result" binding:"omitempty"`
UserID uint `json:"user_id" binding:"omitempty"`
SeedPeerClusterIDs []uint `json:"seed_peer_cluster_ids" binding:"omitempty"`
CDNClusterIDs []uint `json:"cdn_cluster_ids" binding:"omitempty"`
SchedulerClusterIDs []uint `json:"scheduler_cluster_ids" binding:"omitempty"`
}

View File

@ -21,25 +21,23 @@ type SchedulerParams struct {
}
type CreateSchedulerRequest struct {
HostName string `json:"host_name" binding:"required"`
VIPs string `json:"vips" binding:"omitempty"`
IDC string `json:"idc" binding:"required"`
Location string `json:"location" binding:"omitempty"`
NetConfig map[string]interface{} `json:"net_config" binding:"omitempty"`
IP string `json:"ip" binding:"required"`
Port int32 `json:"port" binding:"required"`
SchedulerClusterID uint `json:"scheduler_cluster_id" binding:"required"`
HostName string `json:"host_name" binding:"required"`
IDC string `json:"idc" binding:"omitempty"`
NetTopology string `json:"net_topology" binding:"omitempty"`
Location string `json:"location" binding:"omitempty"`
IP string `json:"ip" binding:"required"`
Port int32 `json:"port" binding:"required"`
SchedulerClusterID uint `json:"scheduler_cluster_id" binding:"required"`
}
type UpdateSchedulerRequest struct {
VIPs string `json:"vips" binding:"omitempty"`
IDC string `json:"idc" binding:"omitempty"`
Location string `json:"location" binding:"omitempty"`
NetConfig map[string]interface{} `json:"net_config" binding:"omitempty"`
IP string `json:"ip" binding:"omitempty"`
Port int32 `json:"port" binding:"omitempty"`
SchedulerID uint `json:"scheduler_id" binding:"omitempty"`
SchedulerClusterID uint `json:"scheduler_cluster_id" binding:"omitempty"`
IDC string `json:"idc" binding:"omitempty"`
NetTopology string `json:"net_topology" binding:"omitempty"`
Location string `json:"location" binding:"omitempty"`
IP string `json:"ip" binding:"omitempty"`
Port int32 `json:"port" binding:"omitempty"`
SchedulerID uint `json:"scheduler_id" binding:"omitempty"`
SchedulerClusterID uint `json:"scheduler_cluster_id" binding:"omitempty"`
}
type GetSchedulersQuery struct {

View File

@ -26,23 +26,25 @@ type AddSchedulerToSchedulerClusterParams struct {
}
type CreateSchedulerClusterRequest struct {
Name string `json:"name" binding:"required"`
BIO string `json:"bio" binding:"omitempty"`
Config *SchedulerClusterConfig `json:"config" binding:"required"`
ClientConfig *SchedulerClusterClientConfig `json:"client_config" binding:"required"`
Scopes *SchedulerClusterScopes `json:"scopes" binding:"omitempty"`
IsDefault bool `json:"is_default" binding:"omitempty"`
CDNClusterID uint `json:"cdn_cluster_id" binding:"omitempty"`
Name string `json:"name" binding:"required"`
BIO string `json:"bio" binding:"omitempty"`
Config *SchedulerClusterConfig `json:"config" binding:"required"`
ClientConfig *SchedulerClusterClientConfig `json:"client_config" binding:"required"`
Scopes *SchedulerClusterScopes `json:"scopes" binding:"omitempty"`
IsDefault bool `json:"is_default" binding:"omitempty"`
SeedPeerClusterID uint `json:"seed_peer_cluster_id" binding:"omitempty"`
CDNClusterID uint `json:"cdn_cluster_id" binding:"omitempty"`
}
type UpdateSchedulerClusterRequest struct {
Name string `json:"name" binding:"omitempty"`
BIO string `json:"bio" binding:"omitempty"`
Config *SchedulerClusterConfig `json:"config" binding:"omitempty"`
ClientConfig *SchedulerClusterClientConfig `json:"client_config" binding:"omitempty"`
Scopes *SchedulerClusterScopes `json:"scopes" binding:"omitempty"`
IsDefault bool `json:"is_default" binding:"omitempty"`
CDNClusterID uint `json:"cdn_cluster_id" binding:"omitempty"`
Name string `json:"name" binding:"omitempty"`
BIO string `json:"bio" binding:"omitempty"`
Config *SchedulerClusterConfig `json:"config" binding:"omitempty"`
ClientConfig *SchedulerClusterClientConfig `json:"client_config" binding:"omitempty"`
Scopes *SchedulerClusterScopes `json:"scopes" binding:"omitempty"`
IsDefault bool `json:"is_default" binding:"omitempty"`
SeedPeerClusterID uint `json:"seed_peer_cluster_id" binding:"omitempty"`
CDNClusterID uint `json:"cdn_cluster_id" binding:"omitempty"`
}
type GetSchedulerClustersQuery struct {

View File

@ -25,6 +25,11 @@ type AddSchedulerClusterToSecurityGroupParams struct {
SchedulerClusterID uint `uri:"scheduler_cluster_id" binding:"required"`
}
type AddSeedPeerClusterToSecurityGroupParams struct {
ID uint `uri:"id" binding:"required"`
SeedPeerClusterID uint `uri:"seed_peer_cluster_id" binding:"required"`
}
type AddCDNClusterToSecurityGroupParams struct {
ID uint `uri:"id" binding:"required"`
CDNClusterID uint `uri:"cdn_cluster_id" binding:"required"`

View File

@ -0,0 +1,58 @@
/*
* Copyright 2022 The Dragonfly 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 types
type SeedPeerParams struct {
ID uint `uri:"id" binding:"required"`
}
type CreateSeedPeerRequest struct {
HostName string `json:"host_name" binding:"required"`
Type string `json:"type" binding:"required"`
IDC string `json:"idc" binding:"omitempty"`
NetTopology string `json:"net_topology" binding:"omitempty"`
Location string `json:"location" binding:"omitempty"`
IP string `json:"ip" binding:"required"`
Port int32 `json:"port" binding:"required"`
DownloadPort int32 `json:"download_port" binding:"required"`
SeedPeerClusterID uint `json:"seed_peer_cluster_id" binding:"required"`
}
type UpdateSeedPeerRequest struct {
Type string `json:"type" binding:"omitempty"`
IDC string `json:"idc" binding:"omitempty"`
NetTopology string `json:"net_topology" binding:"omitempty"`
Location string `json:"location" binding:"omitempty"`
IP string `json:"ip" binding:"omitempty"`
Port int32 `json:"port" binding:"omitempty"`
DownloadPort int32 `json:"download_port" binding:"omitempty"`
SeedPeerClusterID uint `json:"seed_peer_cluster_id" binding:"omitempty"`
}
type GetSeedPeersQuery struct {
HostName string `form:"host_name" binding:"omitempty"`
Type string `form:"type" binding:"omitempty"`
IDC string `form:"idc" binding:"omitempty"`
Location string `form:"location" binding:"omitempty"`
IP string `form:"ip" binding:"omitempty"`
Port int32 `form:"port" binding:"omitempty"`
DownloadPort int32 `form:"download_port" binding:"omitempty"`
SeedPeerClusterID uint `form:"seed_peer_cluster_id" binding:"omitempty"`
Page int `form:"page" binding:"omitempty,gte=1"`
PerPage int `form:"per_page" binding:"omitempty,gte=1,lte=50"`
State string `form:"state" binding:"omitempty,oneof=active inactive"`
}

View File

@ -0,0 +1,63 @@
/*
* Copyright 2022 The Dragonfly 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 types
type SeedPeerClusterParams struct {
ID uint `uri:"id" binding:"required"`
}
type AddSeedPeerToSeedPeerClusterParams struct {
ID uint `uri:"id" binding:"required"`
SeedPeerID uint `uri:"seed_peer_id" binding:"required"`
}
type AddSchedulerClusterToSeedPeerClusterParams struct {
ID uint `uri:"id" binding:"required"`
SchedulerClusterID uint `uri:"scheduler_cluster_id" binding:"required"`
}
type CreateSeedPeerClusterRequest struct {
Name string `json:"name" binding:"required"`
BIO string `json:"bio" binding:"omitempty"`
Config *SeedPeerClusterConfig `json:"config" binding:"required"`
Scopes *SeedPeerClusterScopes `json:"scopes" binding:"omitempty"`
IsDefault bool `json:"is_default" binding:"omitempty"`
}
type UpdateSeedPeerClusterRequest struct {
Name string `json:"name" binding:"omitempty"`
BIO string `json:"bio" binding:"omitempty"`
Config *SeedPeerClusterConfig `json:"config" binding:"omitempty"`
Scopes *SeedPeerClusterScopes `json:"scopes" binding:"omitempty"`
IsDefault bool `json:"is_default" binding:"omitempty"`
}
type GetSeedPeerClustersQuery struct {
Name string `form:"name" binding:"omitempty"`
Page int `form:"page" binding:"omitempty,gte=1"`
PerPage int `form:"per_page" binding:"omitempty,gte=1,lte=50"`
}
type SeedPeerClusterConfig struct {
LoadLimit uint32 `yaml:"loadLimit" mapstructure:"loadLimit" json:"load_limit" binding:"omitempty,gte=1,lte=5000"`
}
type SeedPeerClusterScopes struct {
IDC string `yaml:"idc" mapstructure:"idc" json:"idc" binding:"omitempty"`
NetTopology string `yaml:"net_topology" mapstructure:"net_topology" json:"net_topology" binding:"omitempty"`
Location string `yaml:"location" mapstructure:"location" json:"location" binding:"omitempty"`
}

View File

@ -14,6 +14,8 @@
* limitations under the License.
*/
//go:generate mockgen -destination mocks/client_mock.go -source client.go -package mocks
package client
import (
@ -43,22 +45,25 @@ const (
)
type Client interface {
// Get Scheduler and Scheduler cluster configuration
GetScheduler(*manager.GetSchedulerRequest) (*manager.Scheduler, error)
// Update Seed peer configuration.
UpdateSeedPeer(*manager.UpdateSeedPeerRequest) (*manager.SeedPeer, error)
// Update scheduler configuration
UpdateScheduler(*manager.UpdateSchedulerRequest) (*manager.Scheduler, error)
// Update CDN configuration
// Update CDN configuration.
UpdateCDN(*manager.UpdateCDNRequest) (*manager.CDN, error)
// List acitve schedulers configuration
// Get Scheduler and Scheduler cluster configuration.
GetScheduler(*manager.GetSchedulerRequest) (*manager.Scheduler, error)
// Update scheduler configuration.
UpdateScheduler(*manager.UpdateSchedulerRequest) (*manager.Scheduler, error)
// List acitve schedulers configuration.
ListSchedulers(*manager.ListSchedulersRequest) (*manager.ListSchedulersResponse, error)
// KeepAlive with manager
// KeepAlive with manager.
KeepAlive(time.Duration, *manager.KeepAliveRequest)
// Close client connect
// Close client connect.
Close() error
}
@ -108,6 +113,20 @@ func NewWithAddrs(netAddrs []dfnet.NetAddr) (Client, error) {
return nil, errors.New("can not find available manager addresses")
}
func (c *client) UpdateSeedPeer(req *manager.UpdateSeedPeerRequest) (*manager.SeedPeer, error) {
ctx, cancel := context.WithTimeout(context.Background(), contextTimeout)
defer cancel()
return c.ManagerClient.UpdateSeedPeer(ctx, req)
}
func (c *client) UpdateCDN(req *manager.UpdateCDNRequest) (*manager.CDN, error) {
ctx, cancel := context.WithTimeout(context.Background(), contextTimeout)
defer cancel()
return c.ManagerClient.UpdateCDN(ctx, req)
}
func (c *client) GetScheduler(req *manager.GetSchedulerRequest) (*manager.Scheduler, error) {
ctx, cancel := context.WithTimeout(context.Background(), contextTimeout)
defer cancel()
@ -122,13 +141,6 @@ func (c *client) UpdateScheduler(req *manager.UpdateSchedulerRequest) (*manager.
return c.ManagerClient.UpdateScheduler(ctx, req)
}
func (c *client) UpdateCDN(req *manager.UpdateCDNRequest) (*manager.CDN, error) {
ctx, cancel := context.WithTimeout(context.Background(), contextTimeout)
defer cancel()
return c.ManagerClient.UpdateCDN(ctx, req)
}
func (c *client) ListSchedulers(req *manager.ListSchedulersRequest) (*manager.ListSchedulersResponse, error) {
ctx, cancel := context.WithTimeout(context.Background(), contextTimeout)
defer cancel()

View File

@ -1,5 +1,5 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: pkg/rpc/manager/client/client.go
// Source: client.go
// Package mocks is a generated GoMock package.
package mocks
@ -120,3 +120,18 @@ func (mr *MockClientMockRecorder) UpdateScheduler(arg0 interface{}) *gomock.Call
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateScheduler", reflect.TypeOf((*MockClient)(nil).UpdateScheduler), arg0)
}
// UpdateSeedPeer mocks base method.
func (m *MockClient) UpdateSeedPeer(arg0 *manager.UpdateSeedPeerRequest) (*manager.SeedPeer, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateSeedPeer", arg0)
ret0, _ := ret[0].(*manager.SeedPeer)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// UpdateSeedPeer indicates an expected call of UpdateSeedPeer.
func (mr *MockClientMockRecorder) UpdateSeedPeer(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateSeedPeer", reflect.TypeOf((*MockClient)(nil).UpdateSeedPeer), arg0)
}

File diff suppressed because it is too large Load Diff

View File

@ -33,6 +33,81 @@ var (
_ = anypb.Any{}
)
// Validate checks the field values on SecurityGroup with the rules defined in
// the proto definition for this message. If any rules are violated, an error
// is returned.
func (m *SecurityGroup) Validate() error {
if m == nil {
return nil
}
// no validation rules for Id
// no validation rules for Name
// no validation rules for Bio
// no validation rules for Domain
// no validation rules for ProxyDomain
return nil
}
// SecurityGroupValidationError is the validation error returned by
// SecurityGroup.Validate if the designated constraints aren't met.
type SecurityGroupValidationError struct {
field string
reason string
cause error
key bool
}
// Field function returns field value.
func (e SecurityGroupValidationError) Field() string { return e.field }
// Reason function returns reason value.
func (e SecurityGroupValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
func (e SecurityGroupValidationError) Cause() error { return e.cause }
// Key function returns key value.
func (e SecurityGroupValidationError) Key() bool { return e.key }
// ErrorName returns error name.
func (e SecurityGroupValidationError) ErrorName() string { return "SecurityGroupValidationError" }
// Error satisfies the builtin error interface
func (e SecurityGroupValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
}
key := ""
if e.key {
key = "key for "
}
return fmt.Sprintf(
"invalid %sSecurityGroup.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
var _ error = SecurityGroupValidationError{}
var _ interface {
Field() string
Reason() string
Key() bool
Cause() error
ErrorName() string
} = SecurityGroupValidationError{}
// Validate checks the field values on CDNCluster with the rules defined in the
// proto definition for this message. If any rules are violated, an error is returned.
func (m *CDNCluster) Validate() error {
@ -115,81 +190,6 @@ var _ interface {
ErrorName() string
} = CDNClusterValidationError{}
// Validate checks the field values on SecurityGroup with the rules defined in
// the proto definition for this message. If any rules are violated, an error
// is returned.
func (m *SecurityGroup) Validate() error {
if m == nil {
return nil
}
// no validation rules for Id
// no validation rules for Name
// no validation rules for Bio
// no validation rules for Domain
// no validation rules for ProxyDomain
return nil
}
// SecurityGroupValidationError is the validation error returned by
// SecurityGroup.Validate if the designated constraints aren't met.
type SecurityGroupValidationError struct {
field string
reason string
cause error
key bool
}
// Field function returns field value.
func (e SecurityGroupValidationError) Field() string { return e.field }
// Reason function returns reason value.
func (e SecurityGroupValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
func (e SecurityGroupValidationError) Cause() error { return e.cause }
// Key function returns key value.
func (e SecurityGroupValidationError) Key() bool { return e.key }
// ErrorName returns error name.
func (e SecurityGroupValidationError) ErrorName() string { return "SecurityGroupValidationError" }
// Error satisfies the builtin error interface
func (e SecurityGroupValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
}
key := ""
if e.key {
key = "key for "
}
return fmt.Sprintf(
"invalid %sSecurityGroup.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
var _ error = SecurityGroupValidationError{}
var _ interface {
Field() string
Reason() string
Key() bool
Cause() error
ErrorName() string
} = SecurityGroupValidationError{}
// Validate checks the field values on CDN with the rules defined in the proto
// definition for this message. If any rules are violated, an error is returned.
func (m *CDN) Validate() error {
@ -574,6 +574,501 @@ var _ interface {
ErrorName() string
} = UpdateCDNRequestValidationError{}
// Validate checks the field values on SeedPeerCluster with the rules defined
// in the proto definition for this message. If any rules are violated, an
// error is returned.
func (m *SeedPeerCluster) Validate() error {
if m == nil {
return nil
}
// no validation rules for Id
// no validation rules for Name
// no validation rules for Bio
// no validation rules for Config
// no validation rules for Scopes
if v, ok := interface{}(m.GetSecurityGroup()).(interface{ Validate() error }); ok {
if err := v.Validate(); err != nil {
return SeedPeerClusterValidationError{
field: "SecurityGroup",
reason: "embedded message failed validation",
cause: err,
}
}
}
return nil
}
// SeedPeerClusterValidationError is the validation error returned by
// SeedPeerCluster.Validate if the designated constraints aren't met.
type SeedPeerClusterValidationError struct {
field string
reason string
cause error
key bool
}
// Field function returns field value.
func (e SeedPeerClusterValidationError) Field() string { return e.field }
// Reason function returns reason value.
func (e SeedPeerClusterValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
func (e SeedPeerClusterValidationError) Cause() error { return e.cause }
// Key function returns key value.
func (e SeedPeerClusterValidationError) Key() bool { return e.key }
// ErrorName returns error name.
func (e SeedPeerClusterValidationError) ErrorName() string { return "SeedPeerClusterValidationError" }
// Error satisfies the builtin error interface
func (e SeedPeerClusterValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
}
key := ""
if e.key {
key = "key for "
}
return fmt.Sprintf(
"invalid %sSeedPeerCluster.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
var _ error = SeedPeerClusterValidationError{}
var _ interface {
Field() string
Reason() string
Key() bool
Cause() error
ErrorName() string
} = SeedPeerClusterValidationError{}
// Validate checks the field values on SeedPeer with the rules defined in the
// proto definition for this message. If any rules are violated, an error is returned.
func (m *SeedPeer) Validate() error {
if m == nil {
return nil
}
// no validation rules for Id
// no validation rules for HostName
// no validation rules for Type
// no validation rules for Idc
// no validation rules for NetTopology
// no validation rules for Location
// no validation rules for Ip
// no validation rules for Port
// no validation rules for DownloadPort
// no validation rules for State
// no validation rules for SeedPeerClusterId
if v, ok := interface{}(m.GetSeedPeerCluster()).(interface{ Validate() error }); ok {
if err := v.Validate(); err != nil {
return SeedPeerValidationError{
field: "SeedPeerCluster",
reason: "embedded message failed validation",
cause: err,
}
}
}
for idx, item := range m.GetSchedulers() {
_, _ = idx, item
if v, ok := interface{}(item).(interface{ Validate() error }); ok {
if err := v.Validate(); err != nil {
return SeedPeerValidationError{
field: fmt.Sprintf("Schedulers[%v]", idx),
reason: "embedded message failed validation",
cause: err,
}
}
}
}
return nil
}
// SeedPeerValidationError is the validation error returned by
// SeedPeer.Validate if the designated constraints aren't met.
type SeedPeerValidationError struct {
field string
reason string
cause error
key bool
}
// Field function returns field value.
func (e SeedPeerValidationError) Field() string { return e.field }
// Reason function returns reason value.
func (e SeedPeerValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
func (e SeedPeerValidationError) Cause() error { return e.cause }
// Key function returns key value.
func (e SeedPeerValidationError) Key() bool { return e.key }
// ErrorName returns error name.
func (e SeedPeerValidationError) ErrorName() string { return "SeedPeerValidationError" }
// Error satisfies the builtin error interface
func (e SeedPeerValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
}
key := ""
if e.key {
key = "key for "
}
return fmt.Sprintf(
"invalid %sSeedPeer.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
var _ error = SeedPeerValidationError{}
var _ interface {
Field() string
Reason() string
Key() bool
Cause() error
ErrorName() string
} = SeedPeerValidationError{}
// Validate checks the field values on GetSeedPeerRequest with the rules
// defined in the proto definition for this message. If any rules are
// violated, an error is returned.
func (m *GetSeedPeerRequest) Validate() error {
if m == nil {
return nil
}
if _, ok := SourceType_name[int32(m.GetSourceType())]; !ok {
return GetSeedPeerRequestValidationError{
field: "SourceType",
reason: "value must be one of the defined enum values",
}
}
if err := m._validateHostname(m.GetHostName()); err != nil {
return GetSeedPeerRequestValidationError{
field: "HostName",
reason: "value must be a valid hostname",
cause: err,
}
}
if m.GetSeedPeerClusterId() < 1 {
return GetSeedPeerRequestValidationError{
field: "SeedPeerClusterId",
reason: "value must be greater than or equal to 1",
}
}
return nil
}
func (m *GetSeedPeerRequest) _validateHostname(host string) error {
s := strings.ToLower(strings.TrimSuffix(host, "."))
if len(host) > 253 {
return errors.New("hostname cannot exceed 253 characters")
}
for _, part := range strings.Split(s, ".") {
if l := len(part); l == 0 || l > 63 {
return errors.New("hostname part must be non-empty and cannot exceed 63 characters")
}
if part[0] == '-' {
return errors.New("hostname parts cannot begin with hyphens")
}
if part[len(part)-1] == '-' {
return errors.New("hostname parts cannot end with hyphens")
}
for _, r := range part {
if (r < 'a' || r > 'z') && (r < '0' || r > '9') && r != '-' {
return fmt.Errorf("hostname parts can only contain alphanumeric characters or hyphens, got %q", string(r))
}
}
}
return nil
}
// GetSeedPeerRequestValidationError is the validation error returned by
// GetSeedPeerRequest.Validate if the designated constraints aren't met.
type GetSeedPeerRequestValidationError struct {
field string
reason string
cause error
key bool
}
// Field function returns field value.
func (e GetSeedPeerRequestValidationError) Field() string { return e.field }
// Reason function returns reason value.
func (e GetSeedPeerRequestValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
func (e GetSeedPeerRequestValidationError) Cause() error { return e.cause }
// Key function returns key value.
func (e GetSeedPeerRequestValidationError) Key() bool { return e.key }
// ErrorName returns error name.
func (e GetSeedPeerRequestValidationError) ErrorName() string {
return "GetSeedPeerRequestValidationError"
}
// Error satisfies the builtin error interface
func (e GetSeedPeerRequestValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
}
key := ""
if e.key {
key = "key for "
}
return fmt.Sprintf(
"invalid %sGetSeedPeerRequest.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
var _ error = GetSeedPeerRequestValidationError{}
var _ interface {
Field() string
Reason() string
Key() bool
Cause() error
ErrorName() string
} = GetSeedPeerRequestValidationError{}
// Validate checks the field values on UpdateSeedPeerRequest with the rules
// defined in the proto definition for this message. If any rules are
// violated, an error is returned.
func (m *UpdateSeedPeerRequest) Validate() error {
if m == nil {
return nil
}
if _, ok := SourceType_name[int32(m.GetSourceType())]; !ok {
return UpdateSeedPeerRequestValidationError{
field: "SourceType",
reason: "value must be one of the defined enum values",
}
}
if err := m._validateHostname(m.GetHostName()); err != nil {
return UpdateSeedPeerRequestValidationError{
field: "HostName",
reason: "value must be a valid hostname",
cause: err,
}
}
if l := utf8.RuneCountInString(m.GetType()); l < 1 || l > 1024 {
return UpdateSeedPeerRequestValidationError{
field: "Type",
reason: "value length must be between 1 and 1024 runes, inclusive",
}
}
if m.GetIdc() != "" {
if l := utf8.RuneCountInString(m.GetIdc()); l < 1 || l > 1024 {
return UpdateSeedPeerRequestValidationError{
field: "Idc",
reason: "value length must be between 1 and 1024 runes, inclusive",
}
}
}
if m.GetNetTopology() != "" {
if l := utf8.RuneCountInString(m.GetNetTopology()); l < 1 || l > 1024 {
return UpdateSeedPeerRequestValidationError{
field: "NetTopology",
reason: "value length must be between 1 and 1024 runes, inclusive",
}
}
}
if m.GetLocation() != "" {
if utf8.RuneCountInString(m.GetLocation()) > 1024 {
return UpdateSeedPeerRequestValidationError{
field: "Location",
reason: "value length must be at most 1024 runes",
}
}
}
if ip := net.ParseIP(m.GetIp()); ip == nil {
return UpdateSeedPeerRequestValidationError{
field: "Ip",
reason: "value must be a valid IP address",
}
}
if val := m.GetPort(); val < 1024 || val >= 65535 {
return UpdateSeedPeerRequestValidationError{
field: "Port",
reason: "value must be inside range [1024, 65535)",
}
}
if val := m.GetDownloadPort(); val < 1024 || val >= 65535 {
return UpdateSeedPeerRequestValidationError{
field: "DownloadPort",
reason: "value must be inside range [1024, 65535)",
}
}
if m.GetSeedPeerClusterId() < 1 {
return UpdateSeedPeerRequestValidationError{
field: "SeedPeerClusterId",
reason: "value must be greater than or equal to 1",
}
}
return nil
}
func (m *UpdateSeedPeerRequest) _validateHostname(host string) error {
s := strings.ToLower(strings.TrimSuffix(host, "."))
if len(host) > 253 {
return errors.New("hostname cannot exceed 253 characters")
}
for _, part := range strings.Split(s, ".") {
if l := len(part); l == 0 || l > 63 {
return errors.New("hostname part must be non-empty and cannot exceed 63 characters")
}
if part[0] == '-' {
return errors.New("hostname parts cannot begin with hyphens")
}
if part[len(part)-1] == '-' {
return errors.New("hostname parts cannot end with hyphens")
}
for _, r := range part {
if (r < 'a' || r > 'z') && (r < '0' || r > '9') && r != '-' {
return fmt.Errorf("hostname parts can only contain alphanumeric characters or hyphens, got %q", string(r))
}
}
}
return nil
}
// UpdateSeedPeerRequestValidationError is the validation error returned by
// UpdateSeedPeerRequest.Validate if the designated constraints aren't met.
type UpdateSeedPeerRequestValidationError struct {
field string
reason string
cause error
key bool
}
// Field function returns field value.
func (e UpdateSeedPeerRequestValidationError) Field() string { return e.field }
// Reason function returns reason value.
func (e UpdateSeedPeerRequestValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
func (e UpdateSeedPeerRequestValidationError) Cause() error { return e.cause }
// Key function returns key value.
func (e UpdateSeedPeerRequestValidationError) Key() bool { return e.key }
// ErrorName returns error name.
func (e UpdateSeedPeerRequestValidationError) ErrorName() string {
return "UpdateSeedPeerRequestValidationError"
}
// Error satisfies the builtin error interface
func (e UpdateSeedPeerRequestValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
}
key := ""
if e.key {
key = "key for "
}
return fmt.Sprintf(
"invalid %sUpdateSeedPeerRequest.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
var _ error = UpdateSeedPeerRequestValidationError{}
var _ interface {
Field() string
Reason() string
Key() bool
Cause() error
ErrorName() string
} = UpdateSeedPeerRequestValidationError{}
// Validate checks the field values on SchedulerCluster with the rules defined
// in the proto definition for this message. If any rules are violated, an
// error is returned.
@ -592,6 +1087,8 @@ func (m *SchedulerCluster) Validate() error {
// no validation rules for ClientConfig
// no validation rules for Scopes
if v, ok := interface{}(m.GetSecurityGroup()).(interface{ Validate() error }); ok {
if err := v.Validate(); err != nil {
return SchedulerClusterValidationError{
@ -711,6 +1208,23 @@ func (m *Scheduler) Validate() error {
}
for idx, item := range m.GetSeedPeers() {
_, _ = idx, item
if v, ok := interface{}(item).(interface{ Validate() error }); ok {
if err := v.Validate(); err != nil {
return SchedulerValidationError{
field: fmt.Sprintf("SeedPeers[%v]", idx),
reason: "embedded message failed validation",
cause: err,
}
}
}
}
// no validation rules for NetTopology
return nil
}
@ -910,6 +1424,13 @@ func (m *UpdateSchedulerRequest) Validate() error {
}
}
if m.GetSchedulerClusterId() < 1 {
return UpdateSchedulerRequestValidationError{
field: "SchedulerClusterId",
reason: "value must be greater than or equal to 1",
}
}
if m.GetVips() != "" {
if l := utf8.RuneCountInString(m.GetVips()); l < 1 || l > 1024 {
@ -934,10 +1455,10 @@ func (m *UpdateSchedulerRequest) Validate() error {
if m.GetLocation() != "" {
if utf8.RuneCountInString(m.GetLocation()) > 1024 {
if l := utf8.RuneCountInString(m.GetLocation()); l < 1 || l > 1024 {
return UpdateSchedulerRequestValidationError{
field: "Location",
reason: "value length must be at most 1024 runes",
reason: "value length must be between 1 and 1024 runes, inclusive",
}
}
@ -968,11 +1489,15 @@ func (m *UpdateSchedulerRequest) Validate() error {
}
}
if m.GetSchedulerClusterId() < 1 {
return UpdateSchedulerRequestValidationError{
field: "SchedulerClusterId",
reason: "value must be greater than or equal to 1",
if m.GetNetTopology() != "" {
if l := utf8.RuneCountInString(m.GetNetTopology()); l < 1 || l > 1024 {
return UpdateSchedulerRequestValidationError{
field: "NetTopology",
reason: "value length must be between 1 and 1024 runes, inclusive",
}
}
}
return nil

View File

@ -23,130 +23,310 @@ import "validate/validate.proto";
option go_package = "d7y.io/dragonfly/v2/pkg/rpc/manager";
// Request source type.
enum SourceType {
// Scheduler service.
SCHEDULER_SOURCE = 0;
// Dfdaemon service.
CLIENT_SOURCE = 1;
// Deprecated: Use SuperSeed type of SeedPeer instead.
CDN_SOURCE = 2;
// SeedPeer service.
SEED_PEER_SOURCE = 3;
}
message CDNCluster {
uint64 id = 1;
string name = 2;
string bio = 3;
bytes config = 4;
SecurityGroup security_group = 6;
}
// SecurityGroup represents security group of cluster.
message SecurityGroup {
// Group id.
uint64 id = 1;
// Group name.
string name = 2;
// Group biography.
string bio = 3;
// Group domain.
string domain = 4;
// Group proxy domain.
string proxy_domain = 5;
}
message CDN {
// Deprecated: Use SeedPeerCluster instead.
message CDNCluster {
// Cluster id.
uint64 id = 1;
// Cluster name.
string name = 2;
// Cluster biography.
string bio = 3;
// Cluster configuration.
bytes config = 4;
// Security group to which the cdn cluster belongs.
SecurityGroup security_group = 6;
}
// Deprecated: Use SuperSeed type of SeedPeer instead.
message CDN {
// CDN id.
uint64 id = 1;
// CDN hostname.
string host_name = 2;
// CDN idc.
string idc = 3;
// CDN location.
string location = 4;
// CDN ip.
string ip = 5;
// CDN grpc port.
int32 port = 6;
// CDN download port.
int32 download_port = 7;
// CDN state.
string state = 8;
// ID of the cluster to which the cdn belongs.
uint64 cdn_cluster_id = 9;
// Cluster to which the cdn belongs.
CDNCluster cdn_cluster = 10;
// Schedulers included in cdn.
repeated Scheduler schedulers = 11;
}
// Deprecated: Use GetSeedPeerRequest instead.
message GetCDNRequest {
// Request source type.
SourceType source_type = 1 [(validate.rules).enum.defined_only = true];
// CDN hostname.
string host_name = 2 [(validate.rules).string.hostname = true];
// ID of the cluster to which the cdn belongs.
uint64 cdn_cluster_id = 3 [(validate.rules).uint64 = {gte: 1}];
}
// Deprecated: Use UpdateSeedPeerRequest instead.
message UpdateCDNRequest {
// Request source type.
SourceType source_type = 1 [(validate.rules).enum.defined_only = true];
// CDN hostname.
string host_name = 2 [(validate.rules).string.hostname = true];
// CDN idc.
string idc = 3 [(validate.rules).string = {min_len: 1, max_len: 1024, ignore_empty: true}];
// CDN location.
string location = 4 [(validate.rules).string = {max_len: 1024, ignore_empty: true}];
// CDN ip.
string ip = 5 [(validate.rules).string = {ip: true}];
// CDN grpc port.
int32 port = 6 [(validate.rules).int32 = {gte: 1024, lt: 65535}];
// CDN download port.
int32 download_port = 7 [(validate.rules).int32 = {gte: 1024, lt: 65535}];
// ID of the cluster to which the cdn belongs.
uint64 cdn_cluster_id = 8 [(validate.rules).uint64 = {gte: 1}];
}
message SchedulerCluster {
// SeedPeerCluster represents cluster of seed peer.
message SeedPeerCluster {
// Cluster id.
uint64 id = 1;
// Cluster name.
string name = 2;
// Cluster biography.
string bio = 3;
// Cluster configuration.
bytes config = 4;
// Cluster scopes.
bytes scopes = 5;
// Security group to which the seed peer cluster belongs.
SecurityGroup security_group = 6;
}
// SeedPeer represents seed peer for network.
message SeedPeer {
// Seed peer id.
uint64 id = 1;
// Seed peer hostname.
string host_name = 2;
// Seed peer type.
string type = 3;
// Seed peer idc.
string idc = 4;
// Seed peer network topology.
string net_topology = 5;
// Seed peer location.
string location = 6;
// Seed peer ip.
string ip = 7;
// Seed peer grpc port.
int32 port = 8;
// Seed peer download port.
int32 download_port = 9;
// Seed peer state.
string state = 10;
// ID of the cluster to which the seed peer belongs.
uint64 seed_peer_cluster_id = 11;
// Cluster to which the seed peer belongs.
SeedPeerCluster seed_peer_cluster = 12;
// Schedulers included in seed peer.
repeated Scheduler schedulers = 13;
}
// GetSeedPeerRequest represents request of GetSeedPeer.
message GetSeedPeerRequest {
// Request source type.
SourceType source_type = 1 [(validate.rules).enum.defined_only = true];
// Seed peer host_name.
string host_name = 2 [(validate.rules).string.hostname = true];
// ID of the cluster to which the seed peer belongs.
uint64 seed_peer_cluster_id = 3 [(validate.rules).uint64 = {gte: 1}];
}
// UpdateSeedPeerRequest represents request of UpdateSeedPeer.
message UpdateSeedPeerRequest {
// Request source type.
SourceType source_type = 1 [(validate.rules).enum.defined_only = true];
// Seed peer hostname.
string host_name = 2 [(validate.rules).string.hostname = true];
// Seed peer type.
string type = 3 [(validate.rules).string = {min_len: 1, max_len: 1024}];
// Seed peer idc.
string idc = 4 [(validate.rules).string = {min_len: 1, max_len: 1024, ignore_empty: true}];
// Seed peer network topology.
string net_topology = 5 [(validate.rules).string = {min_len: 1, max_len: 1024, ignore_empty: true}];
// Seed peer location.
string location = 6 [(validate.rules).string = {max_len: 1024, ignore_empty: true}];
// Seed peer ip.
string ip = 7 [(validate.rules).string = {ip: true}];
// Seed peer port.
int32 port = 8 [(validate.rules).int32 = {gte: 1024, lt: 65535}];
// Seed peer download port.
int32 download_port = 9 [(validate.rules).int32 = {gte: 1024, lt: 65535}];
// ID of the cluster to which the seed peer belongs.
uint64 seed_peer_cluster_id = 10 [(validate.rules).uint64 = {gte: 1}];
}
// SeedPeerCluster represents cluster of scheduler.
message SchedulerCluster {
// Cluster id.
uint64 id = 1;
// Cluster name.
string name = 2;
// Cluster biography.
string bio = 3;
// Cluster config.
bytes config = 4;
// Cluster client config.
bytes client_config = 5;
// Cluster scopes.
bytes scopes = 6;
// Security group to which the scheduler cluster belongs.
SecurityGroup security_group = 7;
}
// SeedPeerCluster represents scheduler for network.
message Scheduler {
// Scheduler id.
uint64 id = 1;
// Scheduler hostname.
string host_name = 2;
// Deprecated: Do not use.
string vips = 3;
// Scheduler idc.
string idc = 4;
// Scheduler location.
string location = 5;
// Deprecated: Use net_topology instead.
bytes net_config = 6;
// Scheduler ip.
string ip = 7;
// Scheduler grpc port.
int32 port = 8;
// Scheduler state.
string state = 9;
// ID of the cluster to which the scheduler belongs.
uint64 scheduler_cluster_id = 10;
// Cluster to which the scheduler belongs.
SchedulerCluster scheduler_cluster = 11;
// Deprecated: Use seed_peers instead.
repeated CDN cdns = 12;
// Seed peers to which the scheduler belongs.
repeated SeedPeer seed_peers = 13;
// Scheduler network topology.
string net_topology = 14;
}
// GetSchedulerRequest represents request of GetScheduler.
message GetSchedulerRequest {
// Request source type.
SourceType source_type = 1 [(validate.rules).enum.defined_only = true];
// Scheduler hostname.
string host_name = 2 [(validate.rules).string.hostname = true];
// ID of the cluster to which the scheduler belongs.
uint64 scheduler_cluster_id = 3 [(validate.rules).uint64 = {gte: 1}];
}
// UpdateSchedulerRequest represents request of UpdateScheduler.
message UpdateSchedulerRequest {
// Request source type.
SourceType source_type = 1 [(validate.rules).enum.defined_only = true];
// Scheduler hostname.
string host_name = 2 [(validate.rules).string.hostname = true];
string vips = 4 [(validate.rules).string = {min_len: 1, max_len: 1024, ignore_empty: true}];
string idc = 5 [(validate.rules).string = {min_len: 1, max_len: 1024, ignore_empty: true}];
string location = 6 [(validate.rules).string = {max_len: 1024, ignore_empty: true}];
bytes net_config = 7 [(validate.rules).bytes = {min_len: 1, ignore_empty: true}];
string ip = 8 [(validate.rules).string = {ip: true}];
int32 port = 9 [(validate.rules).int32 = {gte: 1024, lt: 65535}];
// ID of the cluster to which the scheduler belongs.
uint64 scheduler_cluster_id = 3 [(validate.rules).uint64 = {gte: 1}];
// Deprecated: Do not use.
string vips = 4 [(validate.rules).string = {min_len: 1, max_len: 1024, ignore_empty: true}];
// Scheduler idc.
string idc = 5 [(validate.rules).string = {min_len: 1, max_len: 1024, ignore_empty: true}];
// Scheduler location.
string location = 6 [(validate.rules).string = {min_len: 1, max_len: 1024, ignore_empty: true}];
// Deprecated: Use net_topology instead.
bytes net_config = 7 [(validate.rules).bytes = {min_len: 1, ignore_empty: true}];
// Scheduler ip.
string ip = 8 [(validate.rules).string = {ip: true}];
// Scheduler port.
int32 port = 9 [(validate.rules).int32 = {gte: 1024, lt: 65535}];
// Scheduler network topology.
string net_topology = 10 [(validate.rules).string = {min_len: 1, max_len: 1024, ignore_empty: true}];
}
// ListSchedulersRequest represents request of ListSchedulers.
message ListSchedulersRequest {
// Request source type.
SourceType source_type = 1 [(validate.rules).enum.defined_only = true];
// Source service hostname.
string host_name = 2 [(validate.rules).string.hostname = true];
// Source service ip.
string ip = 3 [(validate.rules).string.ip = true];
// Source service host infomation.
map<string, string> host_info = 5 [(validate.rules).map.ignore_empty = true];
}
// ListSchedulersResponse represents response of ListSchedulers.
message ListSchedulersResponse {
// Schedulers to which the source service belongs.
repeated Scheduler schedulers = 1;
}
// KeepAliveRequest represents request of KeepAlive.
message KeepAliveRequest {
// Request source type.
SourceType source_type = 1 [(validate.rules).enum.defined_only = true];
// Source service hostname.
string host_name = 2 [(validate.rules).string.hostname = true];
// ID of the cluster to which the source service belongs.
uint64 cluster_id = 3 [(validate.rules).uint64 = {gte: 1}];
}
// Manager RPC Service
// Manager RPC Service.
service Manager {
// Get CDN and CDN cluster configuration
// Get SeedPeer and SeedPeer cluster configuration.
rpc GetSeedPeer(GetSeedPeerRequest) returns(SeedPeer);
// Update SeedPeer configuration.
rpc UpdateSeedPeer(UpdateSeedPeerRequest) returns(SeedPeer);
// Deprecated: Use GetSeedPeer instead.
rpc GetCDN(GetCDNRequest) returns(CDN);
// Update CDN configuration
// Deprecated: Use UpdateSeedPeer instead.
rpc UpdateCDN(UpdateCDNRequest) returns(CDN);
// Get Scheduler and Scheduler cluster configuration
// Get Scheduler and Scheduler cluster configuration.
rpc GetScheduler(GetSchedulerRequest)returns(Scheduler);
// Update scheduler configuration
// Update scheduler configuration.
rpc UpdateScheduler(UpdateSchedulerRequest) returns(Scheduler);
// List acitve schedulers configuration
// List acitve schedulers configuration.
rpc ListSchedulers(ListSchedulersRequest)returns(ListSchedulersResponse);
// KeepAlive with manager
// KeepAlive with manager.
rpc KeepAlive(stream KeepAliveRequest)returns(google.protobuf.Empty);
}

View File

@ -78,6 +78,26 @@ func (mr *MockManagerClientMockRecorder) GetScheduler(ctx, in interface{}, opts
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetScheduler", reflect.TypeOf((*MockManagerClient)(nil).GetScheduler), varargs...)
}
// GetSeedPeer mocks base method.
func (m *MockManagerClient) GetSeedPeer(ctx context.Context, in *manager.GetSeedPeerRequest, opts ...grpc.CallOption) (*manager.SeedPeer, error) {
m.ctrl.T.Helper()
varargs := []interface{}{ctx, in}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "GetSeedPeer", varargs...)
ret0, _ := ret[0].(*manager.SeedPeer)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetSeedPeer indicates an expected call of GetSeedPeer.
func (mr *MockManagerClientMockRecorder) GetSeedPeer(ctx, in interface{}, opts ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{ctx, in}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSeedPeer", reflect.TypeOf((*MockManagerClient)(nil).GetSeedPeer), varargs...)
}
// KeepAlive mocks base method.
func (m *MockManagerClient) KeepAlive(ctx context.Context, opts ...grpc.CallOption) (manager.Manager_KeepAliveClient, error) {
m.ctrl.T.Helper()
@ -158,6 +178,26 @@ func (mr *MockManagerClientMockRecorder) UpdateScheduler(ctx, in interface{}, op
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateScheduler", reflect.TypeOf((*MockManagerClient)(nil).UpdateScheduler), varargs...)
}
// UpdateSeedPeer mocks base method.
func (m *MockManagerClient) UpdateSeedPeer(ctx context.Context, in *manager.UpdateSeedPeerRequest, opts ...grpc.CallOption) (*manager.SeedPeer, error) {
m.ctrl.T.Helper()
varargs := []interface{}{ctx, in}
for _, a := range opts {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "UpdateSeedPeer", varargs...)
ret0, _ := ret[0].(*manager.SeedPeer)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// UpdateSeedPeer indicates an expected call of UpdateSeedPeer.
func (mr *MockManagerClientMockRecorder) UpdateSeedPeer(ctx, in interface{}, opts ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{ctx, in}, opts...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateSeedPeer", reflect.TypeOf((*MockManagerClient)(nil).UpdateSeedPeer), varargs...)
}
// MockManager_KeepAliveClient is a mock of Manager_KeepAliveClient interface.
type MockManager_KeepAliveClient struct {
ctrl *gomock.Controller
@ -348,6 +388,21 @@ func (mr *MockManagerServerMockRecorder) GetScheduler(arg0, arg1 interface{}) *g
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetScheduler", reflect.TypeOf((*MockManagerServer)(nil).GetScheduler), arg0, arg1)
}
// GetSeedPeer mocks base method.
func (m *MockManagerServer) GetSeedPeer(arg0 context.Context, arg1 *manager.GetSeedPeerRequest) (*manager.SeedPeer, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetSeedPeer", arg0, arg1)
ret0, _ := ret[0].(*manager.SeedPeer)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetSeedPeer indicates an expected call of GetSeedPeer.
func (mr *MockManagerServerMockRecorder) GetSeedPeer(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSeedPeer", reflect.TypeOf((*MockManagerServer)(nil).GetSeedPeer), arg0, arg1)
}
// KeepAlive mocks base method.
func (m *MockManagerServer) KeepAlive(arg0 manager.Manager_KeepAliveServer) error {
m.ctrl.T.Helper()
@ -407,6 +462,21 @@ func (mr *MockManagerServerMockRecorder) UpdateScheduler(arg0, arg1 interface{})
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateScheduler", reflect.TypeOf((*MockManagerServer)(nil).UpdateScheduler), arg0, arg1)
}
// UpdateSeedPeer mocks base method.
func (m *MockManagerServer) UpdateSeedPeer(arg0 context.Context, arg1 *manager.UpdateSeedPeerRequest) (*manager.SeedPeer, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateSeedPeer", arg0, arg1)
ret0, _ := ret[0].(*manager.SeedPeer)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// UpdateSeedPeer indicates an expected call of UpdateSeedPeer.
func (mr *MockManagerServerMockRecorder) UpdateSeedPeer(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateSeedPeer", reflect.TypeOf((*MockManagerServer)(nil).UpdateSeedPeer), arg0, arg1)
}
// MockManager_KeepAliveServer is a mock of Manager_KeepAliveServer interface.
type MockManager_KeepAliveServer struct {
ctrl *gomock.Controller

View File

@ -31,7 +31,7 @@ import (
"d7y.io/dragonfly/v2/scheduler/service"
)
// Server is grpc sercer
// Server is grpc server
type Server struct {
// Service interface
service *service.Service