- Add GetMetrics method to MetricsClient interface and implement cluster metrics API - Add QuotaPrecheck service for validating resource quotas before deployment - Add auth DTO with role/permission models and auth handler tests - Add instance diagnostics: mounted NFS volumes, labels, annotations in pod diagnostics - Update workspace handler with GetWorkspace endpoint and shared-user list - Fix monitoring handler to use correct service method name - Add tail_lines fallback in instance handler for snake_case query params - Update nginx config for SSE log streaming support (no buffering) - Add comprehensive test coverage: auth_service_test, auth_handler_test, auth_dto_test, metrics_client_test, quota_precheck_test - Update error messages for quota validation and instance operations - ModifyModal: fix YAML lineWidth:0, modified keys summary, delta-only submit - InstanceCard: correctly disable scale-minus when replicas <= 0 - SidebarLayout: add hover transition for sidebar items - Update todo.md and lessons.md with latest fixes
190 lines
4.6 KiB
Go
190 lines
4.6 KiB
Go
package entity
|
|
|
|
import (
|
|
"time"
|
|
)
|
|
|
|
// InstanceStatus 实例状态
|
|
type InstanceStatus string
|
|
|
|
const (
|
|
StatusDeployed InstanceStatus = "deployed"
|
|
StatusUninstalled InstanceStatus = "uninstalled"
|
|
StatusSuperseded InstanceStatus = "superseded"
|
|
StatusFailed InstanceStatus = "failed"
|
|
StatusPending InstanceStatus = "pending-install"
|
|
StatusUpgrading InstanceStatus = "pending-upgrade"
|
|
StatusRollingBack InstanceStatus = "pending-rollback"
|
|
StatusTerminating InstanceStatus = "pending-delete"
|
|
StatusUnknown InstanceStatus = "unknown"
|
|
)
|
|
|
|
// InstanceOperation 实例操作类型
|
|
type InstanceOperation string
|
|
|
|
const (
|
|
OperationNone InstanceOperation = ""
|
|
OperationInstall InstanceOperation = "install"
|
|
OperationUpgrade InstanceOperation = "upgrade"
|
|
OperationRollback InstanceOperation = "rollback"
|
|
OperationDelete InstanceOperation = "delete"
|
|
OperationSync InstanceOperation = "sync"
|
|
)
|
|
|
|
// Instance Helm 应用实例领域实体
|
|
type Instance struct {
|
|
ID string
|
|
WorkspaceID string
|
|
OwnerID string
|
|
ClusterID string
|
|
Name string // Helm Release Name
|
|
Namespace string
|
|
RegistryID string
|
|
Repository string // OCI Repository (e.g., charts/app)
|
|
Chart string // Chart Name
|
|
Version string // Chart Version
|
|
Description string
|
|
Values map[string]interface{} // Helm Values (JSON)
|
|
ValuesYAML string // Helm Values (YAML format)
|
|
Status InstanceStatus
|
|
StatusReason string
|
|
LastOperation InstanceOperation
|
|
LastError string
|
|
Revision int // Helm Release Revision
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
Replicas int // Running K8s replicas (enriched, not persisted)
|
|
OwnerUsername string
|
|
}
|
|
|
|
// NewInstance 创建新实例
|
|
func NewInstance(clusterID, name, namespace, registryID, repository, chart, version string) *Instance {
|
|
now := time.Now()
|
|
return &Instance{
|
|
ClusterID: clusterID,
|
|
Name: name,
|
|
Namespace: namespace,
|
|
RegistryID: registryID,
|
|
Repository: repository,
|
|
Chart: chart,
|
|
Version: version,
|
|
Status: StatusPending,
|
|
StatusReason: "Pending install",
|
|
LastOperation: OperationInstall,
|
|
Revision: 1,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
}
|
|
}
|
|
|
|
// SetValues 设置 Helm Values
|
|
func (i *Instance) SetValues(values map[string]interface{}) {
|
|
i.Values = values
|
|
i.UpdatedAt = time.Now()
|
|
}
|
|
|
|
// SetValuesYAML 设置 YAML 格式的 Values
|
|
func (i *Instance) SetValuesYAML(yaml string) {
|
|
i.ValuesYAML = yaml
|
|
i.UpdatedAt = time.Now()
|
|
}
|
|
|
|
// UpdateStatus 更新实例状态
|
|
func (i *Instance) UpdateStatus(status InstanceStatus, revision int) {
|
|
i.Status = status
|
|
i.Revision = revision
|
|
i.UpdatedAt = time.Now()
|
|
}
|
|
|
|
// BeginOperation 标记开始执行某个操作
|
|
func (i *Instance) BeginOperation(op InstanceOperation, reason string) {
|
|
i.LastOperation = op
|
|
if pendingStatus := pendingStatusForOperation(op); pendingStatus != "" {
|
|
i.Status = pendingStatus
|
|
}
|
|
if reason != "" {
|
|
i.StatusReason = reason
|
|
}
|
|
i.LastError = ""
|
|
i.UpdatedAt = time.Now()
|
|
}
|
|
|
|
// MarkSuccess 标记操作成功
|
|
func (i *Instance) MarkSuccess(status InstanceStatus, revision int, reason string) {
|
|
if status != "" {
|
|
i.Status = status
|
|
}
|
|
if revision > 0 {
|
|
i.Revision = revision
|
|
}
|
|
i.StatusReason = reason
|
|
i.LastError = ""
|
|
i.UpdatedAt = time.Now()
|
|
}
|
|
|
|
// MarkFailure 标记操作失败
|
|
func (i *Instance) MarkFailure(reason string, err error) {
|
|
i.Status = StatusFailed
|
|
if reason != "" {
|
|
i.StatusReason = reason
|
|
}
|
|
if err != nil {
|
|
i.LastError = err.Error()
|
|
}
|
|
i.UpdatedAt = time.Now()
|
|
}
|
|
|
|
func pendingStatusForOperation(op InstanceOperation) InstanceStatus {
|
|
switch op {
|
|
case OperationInstall:
|
|
return StatusPending
|
|
case OperationUpgrade:
|
|
return StatusUpgrading
|
|
case OperationRollback:
|
|
return StatusRollingBack
|
|
case OperationDelete:
|
|
return StatusTerminating
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
// Upgrade 升级实例
|
|
func (i *Instance) Upgrade(version string, values map[string]interface{}) {
|
|
i.Version = version
|
|
if values != nil {
|
|
i.Values = values
|
|
}
|
|
i.BeginOperation(OperationUpgrade, "Pending upgrade")
|
|
}
|
|
|
|
// Validate 验证实例配置
|
|
func (i *Instance) Validate() error {
|
|
if i.ClusterID == "" {
|
|
return ErrInvalidClusterID
|
|
}
|
|
if i.Name == "" {
|
|
return ErrInvalidInstanceName
|
|
}
|
|
if i.Namespace == "" {
|
|
return ErrInvalidNamespace
|
|
}
|
|
if i.Chart == "" {
|
|
return ErrInvalidChart
|
|
}
|
|
if i.Version == "" {
|
|
return ErrInvalidVersion
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ReleaseHistory Helm Release 历史记录
|
|
type ReleaseHistory struct {
|
|
Revision int
|
|
Updated time.Time
|
|
Status InstanceStatus
|
|
Chart string
|
|
AppVersion string
|
|
Description string
|
|
}
|