diff --git a/devcloud/README.md b/devcloud/README.md index f388387..95954e5 100644 --- a/devcloud/README.md +++ b/devcloud/README.md @@ -1,8 +1,8 @@ # 研发云 devcloud: 研发云, 给产研团队(技术团队), 产品经理, 项目经理, 研发人员/测试人员, 运维(上线,维护) 使用的: DevOps -+ 审计中心: 平台的所有用户操作,记录下来, 变更审计 + 用户中心: 管理用户认证和鉴权 ++ 审计中心: 平台的所有用户操作,记录下来, 变更审计 + 需求管理: Jira, 禅道, ...(x) + 应用管理: 立项后的 SCM 源代码管理, 应用的元数据, 服务树(服务分组) + 资源管理: CMDB diff --git a/devcloud/mpaas/apps/application/README.md b/devcloud/mpaas/apps/application/README.md new file mode 100644 index 0000000..0e52a5c --- /dev/null +++ b/devcloud/mpaas/apps/application/README.md @@ -0,0 +1,3 @@ +# 应用管理 + +应用的核心是代码, 围绕这应用的核心代码, SCM的仓库地址管理 \ No newline at end of file diff --git a/devcloud/mpaas/apps/application/docs/design.drawio b/devcloud/mpaas/apps/application/docs/design.drawio new file mode 100644 index 0000000..3d31cf9 --- /dev/null +++ b/devcloud/mpaas/apps/application/docs/design.drawio @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/devcloud/mpaas/apps/application/enum.go b/devcloud/mpaas/apps/application/enum.go new file mode 100644 index 0000000..2bdd76b --- /dev/null +++ b/devcloud/mpaas/apps/application/enum.go @@ -0,0 +1,112 @@ +package application + +import ( + "bytes" + "fmt" + "slices" + "strings" +) + +const ( + // 源码类型的应用, 需要填写代码仓库信息 + TYPE_SOURCE_CODE TYPE = 0 + // 镜像类型的应用, 需要添加镜像信息 + TYPE_CONTAINER_IMAGE TYPE = 1 + // 其他类型 + TYPE_OTHER TYPE = 15 +) + +// Enum value maps for Type. +var ( + TYPE_NAME = map[TYPE]string{ + TYPE_SOURCE_CODE: "SOURCE_CODE", + TYPE_CONTAINER_IMAGE: "CONTAINER_IMAGE", + TYPE_OTHER: "OTHER", + } + TYPE_VALUE = map[string]TYPE{ + "SOURCE_CODE": TYPE_SOURCE_CODE, + "CONTAINER_IMAGE": TYPE_CONTAINER_IMAGE, + "OTHER": TYPE_OTHER, + } +) + +// ParseTypeFromString Parse Type from string +func ParseTypeFromString(str string) (TYPE, error) { + key := strings.Trim(string(str), `"`) + v, ok := TYPE_VALUE[strings.ToUpper(key)] + if !ok { + return 0, fmt.Errorf("unknown Type: %s", str) + } + + return TYPE(v), nil +} + +type TYPE int32 + +func (t TYPE) String() string { + if name, ok := TYPE_NAME[t]; ok { + return name + } + return fmt.Sprintf("TYPE(%d)", t) +} + +// Equal type compare +func (t TYPE) Equal(target TYPE) bool { + return t == target +} + +// IsIn todo +func (t TYPE) IsIn(targets ...TYPE) bool { + return slices.ContainsFunc(targets, t.Equal) +} + +// MarshalJSON todo +func (t TYPE) MarshalJSON() ([]byte, error) { + b := bytes.NewBufferString(`"`) + b.WriteString(strings.ToUpper(t.String())) + b.WriteString(`"`) + return b.Bytes(), nil +} + +// UnmarshalJSON todo +func (t *TYPE) UnmarshalJSON(b []byte) error { + ins, err := ParseTypeFromString(string(b)) + if err != nil { + return err + } + *t = ins + return nil +} + +// SCM_TYPE 源码仓库类型 +type SCM_PROVIDER string + +const ( + // gitlab + SCM_PROVIDER_GITLAB SCM_PROVIDER = "gitlab" + // github + SCM_PROVIDER_GITHUB SCM_PROVIDER = "github" + // bitbucket + SCM_PROVIDER_BITBUCKET SCM_PROVIDER = "bitbucket" +) + +type LANGUAGE string + +const ( + LANGUAGE_JAVA LANGUAGE = "java" + LANGUAGE_JAVASCRIPT LANGUAGE = "javascript" + LANGUAGE_GOLANG LANGUAGE = "golang" + LANGUAGE_PYTHON LANGUAGE = "python" + LANGUAGE_PHP LANGUAGE = "php" + LANGUAGE_C_SHARP LANGUAGE = "csharp" + LANGUAGE_C LANGUAGE = "c" + LANGUAGE_C_PLUS_PLUS LANGUAGE = "cpp" + LANGUAGE_SWIFT LANGUAGE = "swift" + LANGUAGE_OBJECT_C LANGUAGE = "objectivec" + LANGUAGE_RUST LANGUAGE = "rust" + LANGUAGE_RUBY LANGUAGE = "ruby" + LANGUAGE_DART LANGUAGE = "dart" + LANGUAGE_KOTLIN LANGUAGE = "kotlin" + LANGUAGE_SHELL LANGUAGE = "shell" + LANGUAGE_POWER_SHELL LANGUAGE = "powershell" +) diff --git a/devcloud/mpaas/apps/application/interface.go b/devcloud/mpaas/apps/application/interface.go new file mode 100644 index 0000000..23280a8 --- /dev/null +++ b/devcloud/mpaas/apps/application/interface.go @@ -0,0 +1,45 @@ +package application + +import ( + "context" + + "github.com/infraboard/mcube/v2/types" +) + +type Service interface { + // 创建应用 + CreateApplication(context.Context, CreateApplicationRequest) (*Application, error) + // 查询应用 + QueryApplication(context.Context, QueryApplicationRequest) (*types.Set[*Application], error) + // 更新应用 + UpdateApplication(context.Context, UpdateApplicationRequest) (*Application, error) + // 删除应用 + DeleteApplication(context.Context, DeleteApplicationRequest) (*Application, error) + // 获取应用 + DescribeApplication(context.Context, DescribeApplicationRequest) (*Application, error) +} + +type QueryApplicationRequest struct { + // 应用ID + Id string `json:"id" bson:"_id"` + // 应用名称 + Name string `json:"name" bson:"name"` + // 应用状态 + Status string `json:"status" bson:"status"` +} + +type UpdateApplicationRequest struct { + // 更新人 + UpdateBy string `json:"update_by" bson:"update_by"` + DescribeApplicationRequest + CreateApplicationSpec +} + +type DeleteApplicationRequest struct { + DescribeApplicationRequest +} + +type DescribeApplicationRequest struct { + // 应用ID + Id string `json:"id" bson:"_id"` +} diff --git a/devcloud/mpaas/apps/application/model.go b/devcloud/mpaas/apps/application/model.go index b584a8a..d194f00 100644 --- a/devcloud/mpaas/apps/application/model.go +++ b/devcloud/mpaas/apps/application/model.go @@ -1 +1,92 @@ package application + +import ( + "time" + + "github.com/infraboard/mcube/v2/tools/pretty" +) + +type Application struct { + // 对象Id + Id string `json:"id" bson:"_id"` + // 更新时间 + UpdateAt time.Time `json:"update_at" bson:"update_at"` + // 更新人 + UpdateBy string `json:"update_by" bson:"update_by"` + // 创建请求 + CreateApplicationRequest +} + +func (a *Application) String() string { + return pretty.ToJSON(a) +} + +type CreateApplicationRequest struct { + // 创建人 + CreateBy string `json:"create_by" bson:"create_by" description:"创建人"` + // 创建时间 + CreateAt time.Time `json:"create_at" bson:"create_at"` + // 应用所属空间名称 + Namespace string `json:"namespace" bson:"namespace" description:"应用所属空间名称"` + // 应用创建参数 + CreateApplicationSpec +} + +type CreateApplicationSpec struct { + // 该应用是否已经准备就绪 + Ready bool `json:"ready" bson:"ready" description:"该应用是否已经准备就绪"` + // 应用名称 + Name string `json:"name" bson:"name" description:"应用名称"` + // 应用描述 + Description string `json:"description" bson:"description" description:"应用描述"` + // 应用图标 + Icon string `json:"icon" bson:"icon" description:"应用图标"` + // 应用类型 + Type TYPE `json:"type" bson:"type" description:"应用类型, SOURCE_CODE, CONTAINER_IMAGE, OTHER"` + // 应用代码仓库信息 + CodeRepository CodeRepository `json:"code_repository" bson:"code_repository" description:"应用代码仓库信息"` + // 应用镜像仓库信息 + ImageRepository ImageRepository `json:"image_repository" bson:"image_repository" description:"应用镜像仓库信息"` + // 应用所有者 + Owner string `json:"owner" bson:"owner" description:"应用所有者"` + // 应用等级, 评估这个应用的重要程度 + Level uint32 `json:"level" bson:"level" description:"应用等级, 评估这个应用的重要程度"` + // 应用优先级, 应用启动的先后顺序 + Priority uint32 `json:"priority" bson:"priority" description:"应用优先级, 应用启动的先后顺序"` + // 应用标签 + Labels map[string]string `json:"labels" bson:"labels" description:"应用标签"` +} + +// 服务代码仓库信息 +type CodeRepository struct { + // 仓库提供商 + Provider SCM_PROVIDER `json:"provider" bson:"provider"` + // token 操作仓库, 比如设置回调 + Token string `json:"token" bson:"token"` + // 仓库对应的项目Id + ProjectId string `json:"project_id" bson:"project_id"` + // 仓库对应空间 + Namespace string `json:"namespace" bson:"namespace"` + // 仓库web url地址 + WebUrl string `json:"web_url" bson:"web_url"` + // 仓库ssh url地址 + SshUrl string `json:"ssh_url" bson:"ssh_url"` + // 仓库http url地址 + HttpUrl string `json:"http_url" bson:"http_url"` + // 源代码使用的编程语言, 构建时, 不同语言有不同的构建环境 + Language *LANGUAGE `json:"language" bson:"language"` + // 开启Hook设置 + EnableHook bool `json:"enable_hook" bson:"enable_hook"` + // Hook设置 + HookConfig string `json:"hook_config" bson:"hook_config"` + // scm设置Hook后返回的id, 用于删除应用时,取消hook使用 + HookId string `json:"hook_id" bson:"hook_id"` + // 仓库的创建时间 + CreatedAt time.Time `json:"created_at" bson:"created_at"` +} + +// 镜像仓库 +type ImageRepository struct { + // 服务镜像地址 + Address string `json:"address" bson:"address"` +}