完善应用相关接口
This commit is contained in:
parent
8f28656298
commit
8c58769937
@ -6,8 +6,8 @@ devcloud: 研发云, 给产研团队(技术团队), 产品经理, 项目经理,
|
|||||||
+ 需求管理: Jira, 禅道, ...(x)
|
+ 需求管理: Jira, 禅道, ...(x)
|
||||||
+ 应用管理: 立项后的 SCM 源代码管理, 应用的元数据, 服务树(服务分组)
|
+ 应用管理: 立项后的 SCM 源代码管理, 应用的元数据, 服务树(服务分组)
|
||||||
+ 资源管理: CMDB
|
+ 资源管理: CMDB
|
||||||
+ 应用构建: CI, 流水线发布, 应用的持续构建, Jenkins, 新一代的流程, 基于K8s Job自己设计
|
|
||||||
+ 发布中心(Dev/Test/Pre/Pro)CD: 发布, 应用维护, 部署集群的维护
|
+ 发布中心(Dev/Test/Pre/Pro)CD: 发布, 应用维护, 部署集群的维护
|
||||||
|
+ 应用构建: CI, 流水线发布, 应用的持续构建, Jenkins, 新一代的流程, 基于K8s Job自己设计
|
||||||
|
|
||||||
多业务模块组成, 渐进式微服务开发方式
|
多业务模块组成, 渐进式微服务开发方式
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
_ "122.51.31.227/go-course/go18/devcloud/mcenter/apps"
|
_ "122.51.31.227/go-course/go18/devcloud/mcenter/apps"
|
||||||
// audit 业务对象
|
// audit 业务对象
|
||||||
_ "122.51.31.227/go-course/go18/devcloud/audit/apps"
|
_ "122.51.31.227/go-course/go18/devcloud/audit/apps"
|
||||||
|
// mpaas 应用发布
|
||||||
|
|
||||||
// 非功能性模块
|
// 非功能性模块
|
||||||
_ "github.com/infraboard/mcube/v2/ioc/apps/apidoc/restful"
|
_ "github.com/infraboard/mcube/v2/ioc/apps/apidoc/restful"
|
||||||
|
@ -51,7 +51,7 @@ func (i *PolicyServiceImpl) QueryEndpoint(ctx context.Context, in *policy.QueryE
|
|||||||
|
|
||||||
roleReq := role.NewQueryMatchedEndpointRequest()
|
roleReq := role.NewQueryMatchedEndpointRequest()
|
||||||
policies.ForEach(func(t *policy.Policy) {
|
policies.ForEach(func(t *policy.Policy) {
|
||||||
roleReq.Add(t.RoleId)
|
roleReq.Add(t.RoleId...)
|
||||||
})
|
})
|
||||||
|
|
||||||
if policies.Len() > 0 {
|
if policies.Len() > 0 {
|
||||||
|
@ -2,6 +2,7 @@ package impl
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"slices"
|
||||||
|
|
||||||
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/namespace"
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/namespace"
|
||||||
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/policy"
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/policy"
|
||||||
@ -79,7 +80,7 @@ func (i *PolicyServiceImpl) QueryPolicy(ctx context.Context, in *policy.QueryPol
|
|||||||
if in.WithRole {
|
if in.WithRole {
|
||||||
roleReq := role.NewQueryRoleRequest()
|
roleReq := role.NewQueryRoleRequest()
|
||||||
set.ForEach(func(t *policy.Policy) {
|
set.ForEach(func(t *policy.Policy) {
|
||||||
roleReq.AddRoleId(t.RoleId)
|
roleReq.AddRoleId(t.RoleId...)
|
||||||
})
|
})
|
||||||
roleSet, err := role.GetService().QueryRole(ctx, roleReq)
|
roleSet, err := role.GetService().QueryRole(ctx, roleReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -87,7 +88,7 @@ func (i *PolicyServiceImpl) QueryPolicy(ctx context.Context, in *policy.QueryPol
|
|||||||
}
|
}
|
||||||
set.ForEach(func(p *policy.Policy) {
|
set.ForEach(func(p *policy.Policy) {
|
||||||
p.Role = roleSet.Filter(func(t *role.Role) bool {
|
p.Role = roleSet.Filter(func(t *role.Role) bool {
|
||||||
return p.RoleId == t.Id
|
return slices.Contains(p.RoleId, t.Id)
|
||||||
}).First()
|
}).First()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ func TestCreatePolicy(t *testing.T) {
|
|||||||
req := policy.NewCreatePolicyRequest()
|
req := policy.NewCreatePolicyRequest()
|
||||||
req.SetNamespaceId(1)
|
req.SetNamespaceId(1)
|
||||||
req.UserId = 2
|
req.UserId = 2
|
||||||
req.RoleId = 1
|
req.RoleId = []uint64{1}
|
||||||
set, err := impl.CreatePolicy(ctx, req)
|
set, err := impl.CreatePolicy(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -40,24 +40,24 @@ func (p *Policy) String() string {
|
|||||||
|
|
||||||
func NewCreatePolicyRequest() *CreatePolicyRequest {
|
func NewCreatePolicyRequest() *CreatePolicyRequest {
|
||||||
return &CreatePolicyRequest{
|
return &CreatePolicyRequest{
|
||||||
|
ResourceScope: ResourceScope{
|
||||||
|
Scope: map[string]string{},
|
||||||
|
},
|
||||||
|
RoleId: []uint64{},
|
||||||
Extras: map[string]string{},
|
Extras: map[string]string{},
|
||||||
Scope: map[string]string{},
|
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
ReadOnly: false,
|
ReadOnly: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreatePolicyRequest struct {
|
type CreatePolicyRequest struct {
|
||||||
|
ResourceScope
|
||||||
// 创建者
|
// 创建者
|
||||||
CreateBy uint64 `json:"create_by" bson:"create_by" gorm:"column:create_by;type:uint" description:"创建者" optional:"true"`
|
CreateBy uint64 `json:"create_by" bson:"create_by" gorm:"column:create_by;type:uint" description:"创建者" optional:"true"`
|
||||||
// 空间
|
|
||||||
NamespaceId *uint64 `json:"namespace_id" bson:"namespace_id" gorm:"column:namespace_id;type:varchar(200);index" description:"策略生效的空间Id" optional:"true"`
|
|
||||||
// 用户Id
|
// 用户Id
|
||||||
UserId uint64 `json:"user_id" bson:"user_id" gorm:"column:user_id;type:uint;not null;index" validate:"required" description:"被授权的用户"`
|
UserId uint64 `json:"user_id" bson:"user_id" gorm:"column:user_id;type:uint;not null;index" validate:"required" description:"被授权的用户"`
|
||||||
// 角色Id
|
// 角色Id
|
||||||
RoleId uint64 `json:"role_id" bson:"role_id" gorm:"column:role_id;type:uint;not null;index" validate:"required" description:"被关联的角色"`
|
RoleId []uint64 `json:"role_id" bson:"role_id" gorm:"column:role_id;type:json;not null;serializer:json" validate:"required" description:"被关联的角色"`
|
||||||
// 访问范围, 需要提前定义scope, 比如环境
|
|
||||||
Scope map[string]string `json:"scope" bson:"scope" gorm:"column:scope;serializer:json;type:json" description:"数据访问的范围" optional:"true"`
|
|
||||||
// 策略过期时间
|
// 策略过期时间
|
||||||
ExpiredTime *time.Time `json:"expired_time" bson:"expired_time" gorm:"column:expired_time;type:timestamp;index" description:"策略过期时间" optional:"true"`
|
ExpiredTime *time.Time `json:"expired_time" bson:"expired_time" gorm:"column:expired_time;type:timestamp;index" description:"策略过期时间" optional:"true"`
|
||||||
// 只读策略, 不允许用户修改, 一般用于系统管理
|
// 只读策略, 不允许用户修改, 一般用于系统管理
|
||||||
@ -70,6 +70,13 @@ type CreatePolicyRequest struct {
|
|||||||
Extras map[string]string `json:"extras" bson:"extras" gorm:"column:extras;serializer:json;type:json" description:"扩展信息" optional:"true"`
|
Extras map[string]string `json:"extras" bson:"extras" gorm:"column:extras;serializer:json;type:json" description:"扩展信息" optional:"true"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ResourceScope struct {
|
||||||
|
// 空间
|
||||||
|
NamespaceId *uint64 `json:"namespace_id" bson:"namespace_id" gorm:"column:namespace_id;type:varchar(200);index" description:"策略生效的空间Id" optional:"true"`
|
||||||
|
// 访问范围, 需要提前定义scope, 比如环境, 后端开发小组,开发资源
|
||||||
|
Scope map[string]string `json:"scope" bson:"scope" gorm:"column:scope;serializer:json;type:json" description:"数据访问的范围" optional:"true"`
|
||||||
|
}
|
||||||
|
|
||||||
func (r *CreatePolicyRequest) Validate() error {
|
func (r *CreatePolicyRequest) Validate() error {
|
||||||
return validator.Validate(r)
|
return validator.Validate(r)
|
||||||
}
|
}
|
||||||
|
71
devcloud/mpaas/apps/application/impl/application.go
Normal file
71
devcloud/mpaas/apps/application/impl/application.go
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package impl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mpaas/apps/application"
|
||||||
|
"github.com/infraboard/mcube/v2/ioc/config/datasource"
|
||||||
|
"github.com/infraboard/mcube/v2/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateApplication implements application.Service.
|
||||||
|
func (i *ApplicationServiceImpl) CreateApplication(ctx context.Context, in *application.CreateApplicationRequest) (*application.Application, error) {
|
||||||
|
ins, err := application.NewApplication(*in)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := datasource.DBFromCtx(ctx).
|
||||||
|
Create(ins).
|
||||||
|
Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ins, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryApplication implements application.Service.
|
||||||
|
func (i *ApplicationServiceImpl) QueryApplication(ctx context.Context, in *application.QueryApplicationRequest) (*types.Set[*application.Application], error) {
|
||||||
|
set := types.New[*application.Application]()
|
||||||
|
|
||||||
|
query := datasource.DBFromCtx(ctx).Model(&application.Application{})
|
||||||
|
if in.Id != "" {
|
||||||
|
query = query.Where("id = ?", in.Id)
|
||||||
|
}
|
||||||
|
if in.Name != "" {
|
||||||
|
query = query.Where("name = ?", in.Name)
|
||||||
|
}
|
||||||
|
if in.Ready != nil {
|
||||||
|
query = query.Where("ready = ?", *in.Ready)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := query.Count(&set.Total).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = query.
|
||||||
|
Order("created_at desc").
|
||||||
|
Offset(int(in.ComputeOffset())).
|
||||||
|
Limit(int(in.PageSize)).
|
||||||
|
Find(&set.Items).
|
||||||
|
Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return set, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeApplication implements application.Service.
|
||||||
|
func (i *ApplicationServiceImpl) DescribeApplication(context.Context, *application.DescribeApplicationRequest) (*application.Application, error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateApplication implements application.Service.
|
||||||
|
func (i *ApplicationServiceImpl) UpdateApplication(context.Context, *application.UpdateApplicationRequest) (*application.Application, error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteApplication implements application.Service.
|
||||||
|
func (i *ApplicationServiceImpl) DeleteApplication(context.Context, *application.DeleteApplicationRequest) (*application.Application, error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
31
devcloud/mpaas/apps/application/impl/impl.go
Normal file
31
devcloud/mpaas/apps/application/impl/impl.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package impl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mpaas/apps/application"
|
||||||
|
"github.com/infraboard/mcube/v2/ioc"
|
||||||
|
"github.com/infraboard/mcube/v2/ioc/config/datasource"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
ioc.Controller().Registry(&ApplicationServiceImpl{})
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ application.Service = (*ApplicationServiceImpl)(nil)
|
||||||
|
|
||||||
|
type ApplicationServiceImpl struct {
|
||||||
|
ioc.ObjectImpl
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *ApplicationServiceImpl) Init() error {
|
||||||
|
if datasource.Get().AutoMigrate {
|
||||||
|
err := datasource.DB().AutoMigrate(&application.Application{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *ApplicationServiceImpl) Name() string {
|
||||||
|
return application.APP_NAME
|
||||||
|
}
|
@ -3,29 +3,46 @@ package application
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"122.51.31.227/go-course/go18/devcloud/mcenter/apps/policy"
|
||||||
|
"github.com/infraboard/mcube/v2/http/request"
|
||||||
|
"github.com/infraboard/mcube/v2/ioc"
|
||||||
"github.com/infraboard/mcube/v2/types"
|
"github.com/infraboard/mcube/v2/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
APP_NAME = "application"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetService() Service {
|
||||||
|
return ioc.Controller().Get(APP_NAME).(Service)
|
||||||
|
}
|
||||||
|
|
||||||
type Service interface {
|
type Service interface {
|
||||||
// 创建应用
|
// 创建应用
|
||||||
CreateApplication(context.Context, CreateApplicationRequest) (*Application, error)
|
CreateApplication(context.Context, *CreateApplicationRequest) (*Application, error)
|
||||||
// 查询应用
|
// 查询应用
|
||||||
QueryApplication(context.Context, QueryApplicationRequest) (*types.Set[*Application], error)
|
QueryApplication(context.Context, *QueryApplicationRequest) (*types.Set[*Application], error)
|
||||||
// 更新应用
|
// 更新应用
|
||||||
UpdateApplication(context.Context, UpdateApplicationRequest) (*Application, error)
|
UpdateApplication(context.Context, *UpdateApplicationRequest) (*Application, error)
|
||||||
// 删除应用
|
// 删除应用
|
||||||
DeleteApplication(context.Context, DeleteApplicationRequest) (*Application, error)
|
DeleteApplication(context.Context, *DeleteApplicationRequest) (*Application, error)
|
||||||
// 获取应用
|
// 获取应用
|
||||||
DescribeApplication(context.Context, DescribeApplicationRequest) (*Application, error)
|
DescribeApplication(context.Context, *DescribeApplicationRequest) (*Application, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type QueryApplicationRequest struct {
|
type QueryApplicationRequest struct {
|
||||||
|
*request.PageRequest
|
||||||
|
policy.ResourceScope
|
||||||
|
QueryApplicationRequestSpec
|
||||||
|
}
|
||||||
|
|
||||||
|
type QueryApplicationRequestSpec struct {
|
||||||
// 应用ID
|
// 应用ID
|
||||||
Id string `json:"id" bson:"_id"`
|
Id string `json:"id" bson:"_id"`
|
||||||
// 应用名称
|
// 应用名称
|
||||||
Name string `json:"name" bson:"name"`
|
Name string `json:"name" bson:"name"`
|
||||||
// 应用状态
|
// 应用是否就绪
|
||||||
Status string `json:"status" bson:"status"`
|
Ready *bool `json:"ready" bson:"ready"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateApplicationRequest struct {
|
type UpdateApplicationRequest struct {
|
||||||
|
@ -1,92 +1,189 @@
|
|||||||
package application
|
package application
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/infraboard/mcube/v2/ioc/config/validator"
|
||||||
"github.com/infraboard/mcube/v2/tools/pretty"
|
"github.com/infraboard/mcube/v2/tools/pretty"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func NewApplication(req CreateApplicationRequest) (*Application, error) {
|
||||||
|
app := &Application{
|
||||||
|
CreateApplicationRequest: req,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := app.Validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 动态计算评审状态
|
||||||
|
if len(req.Audits) > 0 {
|
||||||
|
app.SetReady(true)
|
||||||
|
} else {
|
||||||
|
app.SetReady(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
app.BuildId()
|
||||||
|
return app, nil
|
||||||
|
}
|
||||||
|
|
||||||
type Application struct {
|
type Application struct {
|
||||||
// 对象Id
|
// 对象Id
|
||||||
Id string `json:"id" bson:"_id"`
|
Id string `json:"id" bson:"_id" gorm:"column:id;primary_key"`
|
||||||
// 更新时间
|
// 更新时间
|
||||||
UpdateAt time.Time `json:"update_at" bson:"update_at"`
|
UpdateAt time.Time `json:"update_at" bson:"update_at" gorm:"column:update_at"`
|
||||||
// 更新人
|
// 更新人
|
||||||
UpdateBy string `json:"update_by" bson:"update_by"`
|
UpdateBy string `json:"update_by" bson:"update_by" gorm:"column:update_by"`
|
||||||
// 创建请求
|
// 创建请求
|
||||||
CreateApplicationRequest
|
CreateApplicationRequest
|
||||||
|
// 应用状态
|
||||||
|
ApplicationStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Application) TableName() string {
|
||||||
|
return "applications"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Application) String() string {
|
func (a *Application) String() string {
|
||||||
return pretty.ToJSON(a)
|
return pretty.ToJSON(a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *Application) SetReady(v bool) *Application {
|
||||||
|
a.Ready = &v
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Application) BuildId() {
|
||||||
|
bf := bytes.NewBuffer([]byte{})
|
||||||
|
|
||||||
|
switch a.Type {
|
||||||
|
case TYPE_SOURCE_CODE:
|
||||||
|
bf.WriteString(a.CodeRepository.SshUrl)
|
||||||
|
case TYPE_CONTAINER_IMAGE:
|
||||||
|
bf.WriteString(a.GetImageRepositoryPrimaryAddress())
|
||||||
|
}
|
||||||
|
|
||||||
|
a.Id = uuid.NewSHA1(uuid.Nil, bf.Bytes()).String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCreateApplicationRequest() *CreateApplicationRequest {
|
||||||
|
return &CreateApplicationRequest{
|
||||||
|
CreateApplicationSpec: CreateApplicationSpec{
|
||||||
|
Labels: map[string]string{},
|
||||||
|
Extras: map[string]string{},
|
||||||
|
ImageRepository: []ImageRepository{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type CreateApplicationRequest struct {
|
type CreateApplicationRequest struct {
|
||||||
// 创建人
|
// 创建人
|
||||||
CreateBy string `json:"create_by" bson:"create_by" description:"创建人"`
|
CreateBy string `json:"create_by" bson:"create_by" gorm:"column:create_by" description:"创建人"`
|
||||||
// 创建时间
|
// 创建时间
|
||||||
CreateAt time.Time `json:"create_at" bson:"create_at"`
|
CreateAt time.Time `json:"create_at" bson:"create_at" gorm:"column:create_at" description:"创建时间"`
|
||||||
// 应用所属空间名称
|
// 应用所属空间名称
|
||||||
Namespace string `json:"namespace" bson:"namespace" description:"应用所属空间名称"`
|
Namespace string `json:"namespace" bson:"namespace" description:"应用所属空间名称" gorm:"column:namespace"`
|
||||||
// 应用创建参数
|
// 应用创建参数
|
||||||
CreateApplicationSpec
|
CreateApplicationSpec
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *CreateApplicationRequest) Validate() error {
|
||||||
|
return validator.Validate(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *CreateApplicationRequest) GetImageRepositoryPrimaryAddress() string {
|
||||||
|
for _, repo := range a.ImageRepository {
|
||||||
|
if repo.IsPrimary {
|
||||||
|
return repo.Address
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type CreateApplicationSpec struct {
|
type CreateApplicationSpec struct {
|
||||||
// 该应用是否已经准备就绪
|
|
||||||
Ready bool `json:"ready" bson:"ready" description:"该应用是否已经准备就绪"`
|
|
||||||
// 应用名称
|
// 应用名称
|
||||||
Name string `json:"name" bson:"name" description:"应用名称"`
|
Name string `json:"name" bson:"name" gorm:"column:name" description:"应用名称"`
|
||||||
// 应用描述
|
// 应用描述
|
||||||
Description string `json:"description" bson:"description" description:"应用描述"`
|
Description string `json:"description" bson:"description" gorm:"column:description" description:"应用描述"`
|
||||||
// 应用图标
|
// 应用图标
|
||||||
Icon string `json:"icon" bson:"icon" description:"应用图标"`
|
Icon string `json:"icon" bson:"icon" gorm:"column:icons" description:"应用图标"`
|
||||||
// 应用类型
|
// 应用类型
|
||||||
Type TYPE `json:"type" bson:"type" description:"应用类型, SOURCE_CODE, CONTAINER_IMAGE, OTHER"`
|
Type TYPE `json:"type" bson:"type" gorm:"column:type" description:"应用类型, SOURCE_CODE, CONTAINER_IMAGE, OTHER"`
|
||||||
// 应用代码仓库信息
|
// 应用代码仓库信息
|
||||||
CodeRepository CodeRepository `json:"code_repository" bson:"code_repository" description:"应用代码仓库信息"`
|
CodeRepository CodeRepository `json:"code_repository" bson:",inline" gorm:"embedded" description:"应用代码仓库信息"`
|
||||||
// 应用镜像仓库信息
|
// 应用镜像仓库信息
|
||||||
ImageRepository ImageRepository `json:"image_repository" bson:"image_repository" description:"应用镜像仓库信息"`
|
ImageRepository []ImageRepository `json:"image_repository" gorm:"column:image_repository;serializer:json;" bson:"image_repository" description:"应用镜像仓库信息"`
|
||||||
// 应用所有者
|
// 应用所有者
|
||||||
Owner string `json:"owner" bson:"owner" description:"应用所有者"`
|
Owner string `json:"owner" bson:"owner" gorm:"column:owner" description:"应用所有者"`
|
||||||
// 应用等级, 评估这个应用的重要程度
|
// 应用等级, 评估这个应用的重要程度
|
||||||
Level uint32 `json:"level" bson:"level" description:"应用等级, 评估这个应用的重要程度"`
|
Level *uint32 `json:"level" bson:"level" gorm:"column:level" description:"应用等级, 评估这个应用的重要程度"`
|
||||||
// 应用优先级, 应用启动的先后顺序
|
// 应用优先级, 应用启动的先后顺序
|
||||||
Priority uint32 `json:"priority" bson:"priority" description:"应用优先级, 应用启动的先后顺序"`
|
Priority *uint32 `json:"priority" bson:"priority" gorm:"column:priority" description:"应用优先级, 应用启动的先后顺序"`
|
||||||
// 应用标签
|
// 应用标签
|
||||||
Labels map[string]string `json:"labels" bson:"labels" description:"应用标签"`
|
Labels map[string]string `json:"labels" bson:"labels" gorm:"column:labels;serializer:json" description:"应用标签"`
|
||||||
|
// 额外的其他属性
|
||||||
|
Extras map[string]string `json:"extras" form:"extras" bson:"extras" gorm:"column:extras;serializer:json;"`
|
||||||
|
|
||||||
|
// 指定应用的评审方
|
||||||
|
Audits []ApplicationReadyAudit `json:"audits" bson:"audits" gorm:"column:audits;serializer:json" description:"参与应用准备就绪的评审方"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 服务代码仓库信息
|
// 服务代码仓库信息
|
||||||
type CodeRepository struct {
|
type CodeRepository struct {
|
||||||
// 仓库提供商
|
// 仓库提供商
|
||||||
Provider SCM_PROVIDER `json:"provider" bson:"provider"`
|
Provider SCM_PROVIDER `json:"provider" bson:"provider" gorm:"column:provider"`
|
||||||
// token 操作仓库, 比如设置回调
|
// token 操作仓库, 比如设置回调
|
||||||
Token string `json:"token" bson:"token"`
|
Token string `json:"token" bson:"token" gorm:"column:token"`
|
||||||
// 仓库对应的项目Id
|
// 仓库对应的项目Id
|
||||||
ProjectId string `json:"project_id" bson:"project_id"`
|
ProjectId string `json:"project_id" bson:"project_id" gorm:"column:project_id"`
|
||||||
// 仓库对应空间
|
// 仓库对应空间
|
||||||
Namespace string `json:"namespace" bson:"namespace"`
|
Namespace string `json:"namespace" bson:"namespace" gorm:"column:namespace"`
|
||||||
// 仓库web url地址
|
// 仓库web url地址
|
||||||
WebUrl string `json:"web_url" bson:"web_url"`
|
WebUrl string `json:"web_url" bson:"web_url" gorm:"column:web_url"`
|
||||||
// 仓库ssh url地址
|
// 仓库ssh url地址
|
||||||
SshUrl string `json:"ssh_url" bson:"ssh_url"`
|
SshUrl string `json:"ssh_url" bson:"ssh_url" gorm:"column:ssh_url"`
|
||||||
// 仓库http url地址
|
// 仓库http url地址
|
||||||
HttpUrl string `json:"http_url" bson:"http_url"`
|
HttpUrl string `json:"http_url" bson:"http_url" gorm:"column:http_url"`
|
||||||
// 源代码使用的编程语言, 构建时, 不同语言有不同的构建环境
|
// 源代码使用的编程语言, 构建时, 不同语言有不同的构建环境
|
||||||
Language *LANGUAGE `json:"language" bson:"language"`
|
Language *LANGUAGE `json:"language" bson:"language" gorm:"column:language"`
|
||||||
// 开启Hook设置
|
// 开启Hook设置
|
||||||
EnableHook bool `json:"enable_hook" bson:"enable_hook"`
|
EnableHook bool `json:"enable_hook" bson:"enable_hook" gorm:"column:enable_hook"`
|
||||||
// Hook设置
|
// Hook设置
|
||||||
HookConfig string `json:"hook_config" bson:"hook_config"`
|
HookConfig string `json:"hook_config" bson:"hook_config" gorm:"column:hook_config"`
|
||||||
// scm设置Hook后返回的id, 用于删除应用时,取消hook使用
|
// scm设置Hook后返回的id, 用于删除应用时,取消hook使用
|
||||||
HookId string `json:"hook_id" bson:"hook_id"`
|
HookId string `json:"hook_id" bson:"hook_id" gorm:"column:hook_id"`
|
||||||
// 仓库的创建时间
|
// 仓库的创建时间
|
||||||
CreatedAt time.Time `json:"created_at" bson:"created_at"`
|
CreatedAt time.Time `json:"created_at" bson:"created_at" gorm:"column:created_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 镜像仓库
|
// 镜像仓库
|
||||||
type ImageRepository struct {
|
type ImageRepository struct {
|
||||||
// 服务镜像地址
|
// 服务镜像地址, 比如 gcr.lank8s.cn/kaniko-project/executor
|
||||||
Address string `json:"address" bson:"address"`
|
Address string `json:"address" bson:"address"`
|
||||||
|
// 是不是主仓库
|
||||||
|
IsPrimary bool `json:"is_primary" bson:"is_primary"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ApplicationStatus struct {
|
||||||
|
// 该应用是否已经准备就绪,多方确认的一个过程后计算出来的
|
||||||
|
Ready *bool `json:"ready" bson:"ready" gorm:"column:ready" description:"该应用是否已经准备就绪"`
|
||||||
|
// 就绪状态修改时间
|
||||||
|
UpdateAt time.Time `json:"ready_update_at" bson:"ready_update_at" gorm:"column:ready_update_at" description:"就绪状态修改时间"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 参与应用准备就绪的评审方
|
||||||
|
type ApplicationReadyAudit struct {
|
||||||
|
// 评审角色, Dev, Test, Ops
|
||||||
|
RoleName string `json:"role_name"`
|
||||||
|
// 评审人
|
||||||
|
AuditBy string `json:"audit_by"`
|
||||||
|
// 评审时间
|
||||||
|
AuditAt time.Time `json:"audit_at"`
|
||||||
|
// 是否就绪
|
||||||
|
Ready bool `json:"ready"`
|
||||||
|
// 评审建议
|
||||||
|
Message string `json:"message"`
|
||||||
}
|
}
|
||||||
|
@ -1 +1,5 @@
|
|||||||
package apps
|
package apps
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "122.51.31.227/go-course/go18/devcloud/mpaas/apps/application/impl"
|
||||||
|
)
|
||||||
|
84
devcloud/mpaas/design.drawio
Normal file
84
devcloud/mpaas/design.drawio
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<mxfile host="65bd71144e">
|
||||||
|
<diagram id="l8amJ-V2lY7reZdTNxwa" name="第 1 页">
|
||||||
|
<mxGraphModel dx="888" dy="514" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||||
|
<root>
|
||||||
|
<mxCell id="0"/>
|
||||||
|
<mxCell id="1" parent="0"/>
|
||||||
|
<mxCell id="2" value="查询制品" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="3" target="7">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="3" value="artifact<div>制品库</div>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="259" y="70" width="120" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="4" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="5" target="3">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="5" value="CI工具" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="29" y="70" width="120" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="6" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="7" target="11">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="7" value="deploy<div>应用部署</div>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="259" y="220" width="120" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="8" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="10" target="7">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="9" value="选择适合的制品格式<div><br></div>" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="8">
|
||||||
|
<mxGeometry x="0.2278" y="-3" relative="1" as="geometry">
|
||||||
|
<mxPoint x="29" y="-17" as="offset"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="10" value="cluster<div>应用集群</div>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="589" y="220" width="120" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="11" value="k8s 集群" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="259" y="400" width="120" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="12" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="16" target="11">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="13" value="watch" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="12">
|
||||||
|
<mxGeometry x="0.2242" y="-1" relative="1" as="geometry">
|
||||||
|
<mxPoint as="offset"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="14" style="edgeStyle=none;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="16" target="10">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="15" value="实时更新集群状态" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="14">
|
||||||
|
<mxGeometry x="0.0236" y="-4" relative="1" as="geometry">
|
||||||
|
<mxPoint as="offset"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="16" value="sync<div>部署同步</div>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="589" y="400" width="120" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="17" value="首次部署使用模版渲染" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="18" target="10">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="18" value="temlate<div>部署模版</div>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="589" y="70" width="120" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="19" style="edgeStyle=orthogonalEdgeStyle;html=1;exitX=0;exitY=0.3333333333333333;exitDx=0;exitDy=0;exitPerimeter=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="20" target="10">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="20" value="Actor" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="770" y="60" width="30" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="22" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="21" target="10">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="23" value="应用部署" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="22">
|
||||||
|
<mxGeometry x="-0.3768" y="2" relative="1" as="geometry">
|
||||||
|
<mxPoint as="offset"/>
|
||||||
|
</mxGeometry>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="21" value="应用" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="870" y="220" width="120" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
</root>
|
||||||
|
</mxGraphModel>
|
||||||
|
</diagram>
|
||||||
|
</mxfile>
|
1
devcloud/mpaas/registry.go
Normal file
1
devcloud/mpaas/registry.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package mpaas
|
Loading…
x
Reference in New Issue
Block a user