diff --git a/README.md b/README.md index 7bf5092..6155be0 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,8 @@ ChaosMeta is a platform dedicated to supporting all stages of fault drills, cove # core advantages #### Simple and easy to use, provides user interface, low threshold for use Support visual user interface, Kubernetes API, command line, HTTP API, and other methods. -![](docs/static/workflow.png) +[![docs/static/componentlink.png +](docs/static/workflow.png)](https://player.bilibili.com/player.html?aid=276433781&bvid=BV1yF411m7b4&cid=1280401525&p=1) #### Fully verified by a large amount of practical experience, high reliability diff --git a/README_CN.md b/README_CN.md index 87f4f0d..f4d0ff4 100644 --- a/README_CN.md +++ b/README_CN.md @@ -9,7 +9,9 @@ ChaosMeta 是一个致力于支撑故障演练各个阶段的平台,覆盖了 # 核心优势 #### 简单易用,提供用户界面,使用门槛低 支持可视化用户界面、Kubernetes API、命令行、HTTP等多种使用方式 -![](docs/static/workflow.png) + +[![docs/static/componentlink.png +](docs/static/workflow.png)](https://player.bilibili.com/player.html?aid=276433781&bvid=BV1yF411m7b4&cid=1280401525&p=1) #### 大量实践经验充分验证,功能可靠性高 diff --git a/chaosmeta-deploy/templates/chaosmeta-platform-template.yaml b/chaosmeta-deploy/templates/chaosmeta-platform-template.yaml index 346105e..14601b5 100644 --- a/chaosmeta-deploy/templates/chaosmeta-platform-template.yaml +++ b/chaosmeta-deploy/templates/chaosmeta-platform-template.yaml @@ -89,7 +89,7 @@ spec: serviceAccountName: chaosmeta-platform containers: - name: chaosmeta-platform - image: registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-platform:v0.0.6 + image: registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-platform:v0.0.7 resources: requests: cpu: "1" @@ -101,7 +101,7 @@ spec: - name: chaosmeta-config mountPath: /home/admin/conf - name: chaosmeta-platform-frontend - image: registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-platform-frontend:v0.0.3 + image: registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-platform-frontend:v0.0.4 ports: - containerPort: 8000 volumes: diff --git a/chaosmeta-platform-frontend/config/config.ts b/chaosmeta-platform-frontend/config/config.ts index 6d1f00e..53b829c 100644 --- a/chaosmeta-platform-frontend/config/config.ts +++ b/chaosmeta-platform-frontend/config/config.ts @@ -28,12 +28,12 @@ export default defineConfig({ }, proxy: { '/users': { - target: 'http://127.0.0.1/', + target: 'http://127.0.0.1:8082/', changeOrigin: true, pathRewrite: { '^/api': '' }, }, '/chaosmeta': { - target: 'http://127.0.0.1/', + target: 'http://127.0.0.1:8082/', changeOrigin: true, pathRewrite: { '^/api': '' }, }, diff --git a/chaosmeta-platform/pkg/gateway/apiserver/v1alpha1/cluster/cluster.go b/chaosmeta-platform/pkg/gateway/apiserver/v1alpha1/cluster/cluster.go index c0dd98f..f4accad 100644 --- a/chaosmeta-platform/pkg/gateway/apiserver/v1alpha1/cluster/cluster.go +++ b/chaosmeta-platform/pkg/gateway/apiserver/v1alpha1/cluster/cluster.go @@ -36,8 +36,7 @@ func (c *ClusterController) Create() { c.Error(&c.Controller, err) return } - username := c.Ctx.Input.GetData("userName").(string) - log.Error(username, "create:", requestBody.Name) + clusterService := &cluster.ClusterService{} clusterId, err := clusterService.Create(context.Background(), requestBody.Name, requestBody.Kubeconfig) if err != nil { @@ -47,6 +46,7 @@ func (c *ClusterController) Create() { c.Success(&c.Controller, CreateClusterResponse{ ID: clusterId, }) + log.Info(c.Ctx.Input.GetData("userName").(string), "create:", requestBody.Name) } func (c *ClusterController) Get() { @@ -121,12 +121,12 @@ func (c *ClusterController) Delete() { c.Error(&c.Controller, err) return } - username := c.Ctx.Input.GetData("userName").(string) - log.Error(username, "delete:", clusterId) + clusterService := &cluster.ClusterService{} if err := clusterService.Delete(context.Background(), clusterId); err != nil { c.Error(&c.Controller, err) return } c.Success(&c.Controller, "ok") + log.Info(c.Ctx.Input.GetData("userName").(string), "delete:", clusterId) } diff --git a/chaosmeta-platform/pkg/models/experiment/workflow_node.go b/chaosmeta-platform/pkg/models/experiment/workflow_node.go index ea3ad52..80602a0 100644 --- a/chaosmeta-platform/pkg/models/experiment/workflow_node.go +++ b/chaosmeta-platform/pkg/models/experiment/workflow_node.go @@ -18,6 +18,7 @@ package experiment import ( models "chaosmeta-platform/pkg/models/common" + "errors" "github.com/beego/beego/v2/client/orm" ) @@ -33,6 +34,7 @@ type WorkflowNode struct { TargetId int `json:"target_id" orm:"column(target_id); int(11)"` ExecType string `json:"exec_type" orm:"column(exec_type);size(32)"` ExecID int `json:"exec_id" orm:"column(exec_id); int(11)"` + Version int `json:"-" orm:"column(version);default(0);version"` models.BaseTimeModel } @@ -73,6 +75,39 @@ func CreateWorkflowNode(workflowNode *WorkflowNode) error { return err } +func UpdateWorkflowNode(workflowNode *WorkflowNode) error { + o := models.GetORM() + tx, err := o.Begin() + if err != nil { + return err + } + + existing := WorkflowNode{UUID: workflowNode.UUID} + err = tx.Read(&existing) + if err != nil { + tx.Rollback() + return err + } + + if workflowNode.Version != existing.Version { + tx.Rollback() + return errors.New("Concurrent modification detected") + } + + workflowNode.Version = existing.Version + 1 + if _, err = tx.Update(workflowNode); err != nil { + tx.Rollback() + return err + } + + if err = tx.Commit(); err != nil { + tx.Rollback() + return err + } + + return nil +} + func DeleteWorkflowNodeByUUID(uuid string) error { _, err := models.GetORM().QueryTable(new(WorkflowNode).TableName()).Filter("uuid", uuid).Delete() return err diff --git a/chaosmeta-platform/pkg/models/namespace/namespace.go b/chaosmeta-platform/pkg/models/namespace/namespace.go index 995d865..bc755b1 100644 --- a/chaosmeta-platform/pkg/models/namespace/namespace.go +++ b/chaosmeta-platform/pkg/models/namespace/namespace.go @@ -57,6 +57,13 @@ func DeleteNamespace(ctx context.Context, id int) (int64, error) { return num, err } +func GetNamespaceByName(ctx context.Context, namespace *Namespace) error { + if namespace == nil { + return errors.New("namespace is nil") + } + return models.GetORM().Read(namespace, "name") +} + func GetNamespaceById(ctx context.Context, namespace *Namespace) error { if namespace == nil { return errors.New("namespace is nil") diff --git a/chaosmeta-platform/pkg/service/cluster/cluster.go b/chaosmeta-platform/pkg/service/cluster/cluster.go index 24cab72..61a4af4 100644 --- a/chaosmeta-platform/pkg/service/cluster/cluster.go +++ b/chaosmeta-platform/pkg/service/cluster/cluster.go @@ -128,6 +128,12 @@ func (c *ClusterService) GetList(ctx context.Context, name, orderBy string, page } func (c *ClusterService) GetRestConfig(ctx context.Context, id int) (*kubernetes.Clientset, *rest.Config, error) { + if config.DefaultRunOptIns.RunMode == "KubeConfig" { + id = -1 + } + if config.DefaultRunOptIns.RunMode == "ServiceAccount" { + id = 0 + } if id == 0 { return c.getRestConfigInCluster() } diff --git a/chaosmeta-platform/pkg/service/experiment/argo_workflow.go b/chaosmeta-platform/pkg/service/experiment/argo_workflow.go index 2bd9c7a..25b8a59 100644 --- a/chaosmeta-platform/pkg/service/experiment/argo_workflow.go +++ b/chaosmeta-platform/pkg/service/experiment/argo_workflow.go @@ -76,7 +76,7 @@ func (a *argoWorkFlowService) Create(wf v1alpha1.Workflow) (*v1alpha1.Workflow, if err != nil { return nil, err } - log.Errorf("Workflow %s created", createdWorkflow.Name) + log.Infof("Workflow %s created", createdWorkflow.Name) return createdWorkflow, nil } @@ -86,7 +86,7 @@ func (a *argoWorkFlowService) Update(wf v1alpha1.Workflow) (*v1alpha1.Workflow, if err != nil { return nil, err } - log.Errorf("Workflow %s updated", updatedWorkflow.Name) + log.Infof("Workflow %s updated", updatedWorkflow.Name) return updatedWorkflow, nil } diff --git a/chaosmeta-platform/pkg/service/experiment/chaosmeta_inject.go b/chaosmeta-platform/pkg/service/experiment/chaosmeta_inject.go index b1cba9c..a6165dc 100644 --- a/chaosmeta-platform/pkg/service/experiment/chaosmeta_inject.go +++ b/chaosmeta-platform/pkg/service/experiment/chaosmeta_inject.go @@ -208,10 +208,10 @@ func (c *ChaosmetaService) DeleteExpiredList(ctx context.Context) error { if experiment.Status.Status == SuccessStatusType && experiment.Status.CreateTime != "" && experimentCreateTime.Before(expirationTime) { err := c.Delete(ctx, experiment.Name) if err != nil { - log.Errorf("failed to delete chaosmeta experiment %s: %v", experiment.Name, err.Error()) + log.Infof("failed to delete chaosmeta experiment %s: %v", experiment.Name, err.Error()) return err } else { - log.Errorf("chaosmeta experiment %s deleted", experiment.Name) + log.Infof("chaosmeta experiment %s deleted", experiment.Name) } } } diff --git a/chaosmeta-platform/pkg/service/experiment/experiment.go b/chaosmeta-platform/pkg/service/experiment/experiment.go index 0e90052..2e89820 100644 --- a/chaosmeta-platform/pkg/service/experiment/experiment.go +++ b/chaosmeta-platform/pkg/service/experiment/experiment.go @@ -50,6 +50,7 @@ type ExperimentInfo struct { Status int `json:"status"` CreateTime time.Time `json:"create_time,omitempty"` UpdateTime time.Time `json:"update_time,omitempty"` + LastInstance string `json:"last_instance,omitempty"` } type LabelGet struct { @@ -73,7 +74,7 @@ type ExperimentGet struct { ScheduleRule string `json:"schedule_rule"` NamespaceID int `json:"namespace_id"` Creator int `json:"creator,omitempty"` - NextExec time.Time `json:"next_exec,omitempty"` + NextExec string `json:"next_exec,omitempty"` CreatorName string `json:"creator_name,omitempty"` Status int `json:"status"` LastInstance string `json:"last_instance"` @@ -178,15 +179,89 @@ func (es *ExperimentService) UpdateExperiment(uuid string, experimentParam *Expe if experimentParam == nil { return errors.New("experimentParam is nil") } - _, err := experiment.GetExperimentByUUID(uuid) + getExperiment, err := experiment.GetExperimentByUUID(uuid) if err != nil { - return err + return fmt.Errorf("no this experiment") } - if err := es.DeleteExperimentByUUID(uuid); err != nil { - return err + + experimentUUid := getExperiment.UUID + log.Error(1) + //label + if len(experimentParam.Labels) > 0 { + if err := experiment.ClearLabelIDsByExperimentUUID(uuid); err != nil { + log.Error(err) + return err + } + if err := experiment.AddLabelIDsToExperiment(uuid, experimentParam.Labels); err != nil { + log.Error(err) + return err + } } - _, err = es.CreateExperiment(experimentParam) - return err + + //workflow_nodes + for _, node := range experimentParam.WorkflowNodes { + node.ExperimentUUID = experimentUUid + workflowNodeCreate := experiment.WorkflowNode{ + UUID: node.UUID, + Name: node.Name, + ExperimentUUID: experimentUUid, + Row: node.Row, + Column: node.Column, + Duration: node.Duration, + ScopeId: node.ScopeId, + TargetId: node.TargetId, + ExecType: node.ExecType, + ExecID: node.ExecID, + } + + if err := experiment.DeleteWorkflowNodeByUUID(node.UUID); err != nil { + log.Error(err) + return err + } + if err := experiment.CreateWorkflowNode(&workflowNodeCreate); err != nil { + log.Error(err) + return err + } + //args_value + if len(node.ArgsValue) > 0 { + if err := experiment.ClearArgsValuesByWorkflowNodeUUID(node.UUID); err != nil { + log.Error(err) + return err + } + if err := experiment.BatchInsertArgsValues(node.UUID, node.ArgsValue); err != nil { + log.Error(err) + return err + } + } + + //exec_range + if node.FaultRange != nil { + node.FaultRange.WorkflowNodeInstanceUUID = node.UUID + if err := experiment.ClearFaultRangesByWorkflowNodeInstanceUUID(node.UUID); err != nil { + log.Error(err) + return err + } + if err := experiment.CreateFaultRange(node.FaultRange); err != nil { + return err + } + } + } + + if getExperiment.ScheduleType != experimentParam.ScheduleType { + getExperiment.Status = experiment.ToBeExecuted + } + getExperiment.Name = experimentParam.Name + getExperiment.Description = experimentParam.Description + getExperiment.ScheduleType = experimentParam.ScheduleType + getExperiment.ScheduleRule = experimentParam.ScheduleRule + + return experiment.UpdateExperiment(getExperiment) + //experimentParam.Creator = getExperiment.Creator + //if err := es.DeleteExperimentByUUID(uuid); err != nil { + // return err + //} + //_, err = es.CreateExperiment(experimentParam) + //return err } func (es *ExperimentService) UpdateExperimentStatusAndLastInstance(uuid string, status int, lastInstance string) error { @@ -249,13 +324,16 @@ func (es *ExperimentService) GetExperimentByUUID(uuid string) (*ExperimentGet, e NamespaceID: experimentGet.NamespaceID, CreatorName: userGet.Email, Creator: experimentGet.Creator, - NextExec: experimentGet.NextExec, Status: int(experimentGet.Status), LastInstance: experimentGet.LastInstance, CreateTime: experimentGet.CreateTime, UpdateTime: experimentGet.UpdateTime, } + if !experimentGet.NextExec.IsZero() { + experimentReturn.NextExec = experimentGet.NextExec.Format(TimeLayout) + } + experimentCount, _ := experiment_instance.CountExperimentInstances(0, experimentGet.UUID, "", 0) experimentReturn.Number = experimentCount if err := es.GetLabelByExperiment(uuid, &experimentReturn); err != nil { @@ -263,7 +341,6 @@ func (es *ExperimentService) GetExperimentByUUID(uuid string) (*ExperimentGet, e } return &experimentReturn, es.GetWorkflowNodesByExperiment(uuid, &experimentReturn) - //CountExperimentInstances() } diff --git a/chaosmeta-platform/pkg/service/experiment/experiment_flow.go b/chaosmeta-platform/pkg/service/experiment/experiment_flow.go index c34f6da..dcca04a 100644 --- a/chaosmeta-platform/pkg/service/experiment/experiment_flow.go +++ b/chaosmeta-platform/pkg/service/experiment/experiment_flow.go @@ -131,8 +131,8 @@ func GetWorkflowStruct(experimentInstanceId string, nodes []*experiment_instance } newWorkflow.Name = getWorFlowName(experimentInstanceId) newWorkflow.Spec.Templates = append(newWorkflow.Spec.Templates, v1alpha1.Template{ - Name: WorkflowMainStep, - Steps: convertToSteps(experimentInstanceId, nodes), + Name: WorkflowMainStep, + DAG: convertToSteps(experimentInstanceId, nodes), }) return &newWorkflow @@ -142,8 +142,8 @@ func getWaitStepName(experimentInstanceUUID string, nodeId string) string { return fmt.Sprintf("before-wait-%s-%s", experimentInstanceUUID, nodeId) } -func getWaitStep(time string, experimentInstanceUUID string, nodeId string) *v1alpha1.WorkflowStep { - waitStep := v1alpha1.WorkflowStep{ +func getWaitStep(time string, experimentInstanceUUID string, nodeId string) *v1alpha1.DAGTask { + waitStep := v1alpha1.DAGTask{ Name: getWaitStepName(experimentInstanceUUID, nodeId), Template: string(RawSuspend), Arguments: v1alpha1.Arguments{ @@ -162,12 +162,12 @@ func getInjectStepName(scopeName, targetName, experimentInstanceUUID, nodeID str return fmt.Sprintf("inject-%s-%s-%s-%s", scopeName, targetName, experimentInstanceUUID, nodeID) } -func getInjectStep(experimentInstanceUUID string, node *experiment_instance.WorkflowNodesDetail, phaseType PhaseType) *v1alpha1.WorkflowStep { +func getInjectStep(experimentInstanceUUID string, node *experiment_instance.WorkflowNodesDetail, phaseType PhaseType) *v1alpha1.DAGTask { if node == nil { log.Error("node is nil") return nil } - injectStep := v1alpha1.WorkflowStep{ + injectStep := v1alpha1.DAGTask{ Template: string(ExperimentInject), } @@ -226,7 +226,7 @@ func getInjectStep(experimentInstanceUUID string, node *experiment_instance.Work if node.Subtasks.TargetLabel != "" { labelMap := make(map[string]string) for _, pair := range strings.Split(node.Subtasks.TargetLabel, ",") { - parts := strings.Split(pair, "=") + parts := strings.Split(pair, ":") labelMap[strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1]) } selector.Label = labelMap @@ -273,29 +273,6 @@ func getFlowInjectStep(experimentInstanceUUID string, node *experiment_instance. return nil } -func convertToSteps(experimentInstanceId string, nodes []*experiment_instance.WorkflowNodesDetail) []v1alpha1.ParallelSteps { - maxRow, maxColumn := getMaxRowAndColumn(nodes) - steps := make([]v1alpha1.ParallelSteps, maxRow+1) - for i := range steps { - steps[i].Steps = make([]v1alpha1.WorkflowStep, maxColumn+1) - } - step := &v1alpha1.WorkflowStep{} - for _, node := range nodes { - switch node.ExecType { - case string(WaitExecType): - step = getWaitStep(node.Duration, experimentInstanceId, node.UUID) - case string(FaultExecType): - step = getInjectStep(experimentInstanceId, node, InjectPhaseType) - default: - continue - } - if step != nil { - steps[node.Row].Steps[node.Column] = *step - } - } - return steps -} - func getMaxRowAndColumn(nodes []*experiment_instance.WorkflowNodesDetail) (int, int) { maxRow, maxColumn := 0, 0 for _, node := range nodes { @@ -309,6 +286,84 @@ func getMaxRowAndColumn(nodes []*experiment_instance.WorkflowNodesDetail) (int, return maxRow, maxColumn } +func getStepArguments(experimentInstanceId string, node *experiment_instance.WorkflowNodesDetail) *v1alpha1.DAGTask { + if node == nil { + return &v1alpha1.DAGTask{} + } + switch node.ExecType { + case string(WaitExecType): + return getWaitStep(node.Duration, experimentInstanceId, node.UUID) + case string(FaultExecType): + return getInjectStep(experimentInstanceId, node, InjectPhaseType) + default: + return nil + } +} + +func getStepName(experimentInstanceId string, node *experiment_instance.WorkflowNodesDetail) *v1alpha1.DAGTask { + switch node.ExecType { + case string(WaitExecType): + return getWaitStep(node.Duration, experimentInstanceId, node.UUID) + case string(FaultExecType): + return getInjectStep(experimentInstanceId, node, InjectPhaseType) + default: + return nil + } +} + +func convertToSteps(experimentInstanceId string, nodes []*experiment_instance.WorkflowNodesDetail) *v1alpha1.DAGTemplate { + dAGTemplate := v1alpha1.DAGTemplate{} + //_, maxColumn := getMaxRowAndColumn(nodes) + + var steps []v1alpha1.DAGTask + + beginTask := v1alpha1.DAGTask{ + Name: "BeginWaitTask", + Template: string(RawSuspend), + Arguments: v1alpha1.Arguments{ + Parameters: []v1alpha1.Parameter{ + { + Name: "time", + Value: v1alpha1.AnyStringPtr("0s"), + }, + }, + }, + } + endTask := beginTask + endTask.Name = "EndWaitTask" + + steps = append(steps, beginTask) + + var prevNode *experiment_instance.WorkflowNodesDetail + + for _, node := range nodes { + task := *getStepArguments(experimentInstanceId, node) + if prevNode != nil && prevNode.Row != node.Row { + endTask.Dependencies = append(endTask.Dependencies, getStepArguments(experimentInstanceId, prevNode).Name) + //steps = append(steps, task) + log.Debugf("End of row %d\n", prevNode.Row) + + task.Dependencies = []string{"BeginWaitTask"} + } + + log.Debugf("%s(row:%d, column:%d) ", node.Name, node.Row, node.Column) + if node.Column == 0 { + task.Dependencies = []string{"BeginWaitTask"} + } + if prevNode != nil && prevNode.Row == node.Row { + task.Dependencies = []string{getStepArguments(experimentInstanceId, prevNode).Name} + } + + steps = append(steps, task) + prevNode = node + + } + endTask.Dependencies = append(endTask.Dependencies, getStepArguments(experimentInstanceId, prevNode).Name) + steps = append(steps, endTask) + dAGTemplate.Tasks = steps + return &dAGTemplate +} + func getExperimentInstanceIdFromWorkflowName(workflowName string) (string, error) { parts := strings.Split(workflowName, "-") experimentID := "" diff --git a/chaosmeta-platform/pkg/service/experiment/routine.go b/chaosmeta-platform/pkg/service/experiment/routine.go index db6138a..4b1513b 100644 --- a/chaosmeta-platform/pkg/service/experiment/routine.go +++ b/chaosmeta-platform/pkg/service/experiment/routine.go @@ -199,6 +199,15 @@ func StopExperiment(experimentInstanceID string) error { } experimentInstanceInfo.Status = "Succeeded" + for _, node := range workFlowGet.Status.Nodes { + if node.TemplateName == string(ExperimentInject) || node.TemplateName == string(RawSuspend) { + if node.Phase == "Failed" || node.Phase == "Error" { + experimentInstanceInfo.Status = string(node.Phase) + return experimentInstanceModel.UpdateExperimentInstance(experimentInstanceInfo) + } + } + } + return experimentInstanceModel.UpdateExperimentInstance(experimentInstanceInfo) } @@ -211,14 +220,21 @@ func (e *ExperimentRoutine) DealOnceExperiment() { for _, experimentGet := range experiments { nextExec, _ := time.Parse(DefaultFormat, experimentGet.ScheduleRule) - if time.Now().After(nextExec) { + timeNow, _ := time.Parse(DefaultFormat, time.Now().Format(DefaultFormat)) + if timeNow.After(nextExec) { + experimentGet.LastInstance = timeNow.Format(TimeLayout) + log.Info(experimentGet.UUID, " next exec time", experimentGet.NextExec) + if err := experiment.UpdateExperiment(experimentGet); err != nil { + log.Error(err) + continue + } + log.Error("create an experiment") if err := StartExperiment(experimentGet.UUID, ""); err != nil { log.Error(err) continue } experimentGet.Status = experiment.Executed - experimentGet.LastInstance = time.Now().Format(TimeLayout) if err := experiment.UpdateExperiment(experimentGet); err != nil { log.Error(err) continue @@ -253,7 +269,8 @@ func (e *ExperimentRoutine) DealCronExperiment() { if time.Now().After(experimentGet.NextExec) { experimentGet.Status = experiment.Executed experimentGet.NextExec = cronExpr.Next(now) - log.Error(experimentGet.UUID, " next exec time", experimentGet.NextExec) + experimentGet.LastInstance = time.Now().Format(TimeLayout) + log.Info(experimentGet.UUID, " next exec time", experimentGet.NextExec) if err := experiment.UpdateExperiment(experimentGet); err != nil { log.Error(err) continue @@ -264,7 +281,7 @@ func (e *ExperimentRoutine) DealCronExperiment() { } experimentGet.Status = experiment.ToBeExecuted - experimentGet.LastInstance = time.Now().Format(TimeLayout) + if err := experiment.UpdateExperiment(experimentGet); err != nil { log.Error(err) continue diff --git a/chaosmeta-platform/pkg/service/inject/inject.go b/chaosmeta-platform/pkg/service/inject/inject.go index 39a2af3..3dde992 100644 --- a/chaosmeta-platform/pkg/service/inject/inject.go +++ b/chaosmeta-platform/pkg/service/inject/inject.go @@ -37,9 +37,9 @@ const ( ) var ( - PodScope = basic.Scope{Name: string(PodScopeType), NameCn: "Pod", Description: "fault injection can be performed on any Pod in the Kubernetes cluster", DescriptionCn: "可以对 Kubernetes 集群中的任意 Pod 进行故障注入"} - NodeScope = basic.Scope{Name: string(NodeScopeType), NameCn: "Node", Description: "fault injection can be performed on any Node in the Kubernetes cluster", DescriptionCn: "可以对 Kubernetes 集群中的任意 Node 进行故障注入"} - KubernetesScope = basic.Scope{Name: string(KubernetesScopeType), NameCn: "Kubernetes", Description: "faults can be injected into Kubernetes resource instances such as pod, deployment, and node to achieve the exception of the Kubernetes cluster itself or the exception of the operator application", DescriptionCn: "可以对 pod、deployment、node 等Kubernetes资源实例注入故障,达到 Kubernetes 集群自身的异常或者 operator 应用的异常"} + PodScope = basic.Scope{Name: string(PodScopeType), NameCn: "Pod", Description: "Fault injection can be performed on any Pod in the Kubernetes cluster", DescriptionCn: "可以对Kubernetes集群中的任意Pod进行故障注入"} + NodeScope = basic.Scope{Name: string(NodeScopeType), NameCn: "Node", Description: "Fault injection can be performed on any Node in the Kubernetes cluster", DescriptionCn: "可以对Kubernetes集群中的任意Node进行故障注入"} + KubernetesScope = basic.Scope{Name: string(KubernetesScopeType), NameCn: "Kubernetes", Description: "Faults can be injected into Kubernetes resource instances such as pod, deployment, and node to achieve the exception of the Kubernetes cluster itself or the exception of the operator application", DescriptionCn: "可以对Pod、Deployment、Node 等Kubernetes资源实例注入故障,达到Kubernetes集群自身的异常或者operator应用的异常"} ) func Init() error { @@ -83,16 +83,16 @@ func Init() error { func InitTarget(ctx context.Context, scope basic.Scope) error { var ( - CpuTarget = basic.Target{Name: "cpu", NameCn: "cpu", Description: "fault injection capabilities related to cpu faults", DescriptionCn: "cpu故障相关的故障注入能力"} - MemTarget = basic.Target{Name: "mem", NameCn: "mem", Description: "fault injection capabilities related to memory faults", DescriptionCn: "内存故障相关的故障注入能力"} - DiskTarget = basic.Target{Name: "disk", NameCn: "disk", Description: "fault injection capabilities related to disk failures", DescriptionCn: "磁盘故障相关的故障注入能力"} - DiskioTarget = basic.Target{Name: "diskio", NameCn: "diskio", Description: "fault injection capabilities related to disk IO faults", DescriptionCn: "磁盘IO故障相关的故障注入能力"} - NetworkTarget = basic.Target{Name: "network", NameCn: "network", Description: "fault injection capabilities related to disk failures", DescriptionCn: "磁盘故障相关的故障注入能力"} - ProcessTarget = basic.Target{Name: "process", NameCn: "process", Description: "process-dependent fault injection capability", DescriptionCn: "进程相关的故障注入能力"} - FileTarget = basic.Target{Name: "file", NameCn: "file", Description: "file-related fault injection capabilities", DescriptionCn: "文件相关的故障注入能力"} - KernelTarget = basic.Target{Name: "kernel", NameCn: "kernel", Description: "kernel-related fault injection capabilities", DescriptionCn: "内核相关的故障注入能力"} - JvmTarget = basic.Target{Name: "jvm", NameCn: "jvm", Description: "jvm related fault injection capabilities", DescriptionCn: "围绕jvm相关的故障注入能力"} - ContainerTarget = basic.Target{Name: "container", NameCn: "container", Description: "container runtime-related fault injection capabilities", DescriptionCn: "容器运行时相关的故障注入能力"} + CpuTarget = basic.Target{Name: "cpu", NameCn: "cpu", Description: "Fault injection capabilities related to cpu faults", DescriptionCn: "cpu故障相关的故障注入能力"} + MemTarget = basic.Target{Name: "mem", NameCn: "mem", Description: "Fault injection capabilities related to memory faults", DescriptionCn: "内存故障相关的故障注入能力"} + DiskTarget = basic.Target{Name: "disk", NameCn: "disk", Description: "Fault injection capabilities related to disk failures", DescriptionCn: "磁盘故障相关的故障注入能力"} + DiskioTarget = basic.Target{Name: "diskIO", NameCn: "diskIO", Description: "Fault injection capabilities related to disk IO faults", DescriptionCn: "磁盘IO故障相关的故障注入能力"} + NetworkTarget = basic.Target{Name: "network", NameCn: "network", Description: "Fault injection capabilities related to disk failures", DescriptionCn: "磁盘故障相关的故障注入能力"} + ProcessTarget = basic.Target{Name: "process", NameCn: "process", Description: "Process-dependent fault injection capability", DescriptionCn: "进程相关的故障注入能力"} + FileTarget = basic.Target{Name: "file", NameCn: "file", Description: "File-related fault injection capabilities", DescriptionCn: "文件相关的故障注入能力"} + KernelTarget = basic.Target{Name: "kernel", NameCn: "kernel", Description: "Kernel-related fault injection capabilities", DescriptionCn: "内核相关的故障注入能力"} + JvmTarget = basic.Target{Name: "jvm", NameCn: "jvm", Description: "Jvm related fault injection capabilities", DescriptionCn: "围绕jvm相关的故障注入能力"} + ContainerTarget = basic.Target{Name: "container", NameCn: "container", Description: "Container runtime-related fault injection capabilities", DescriptionCn: "容器运行时相关的故障注入能力"} ) CpuTarget.ScopeId = scope.ID @@ -167,8 +167,8 @@ func InitTarget(ctx context.Context, scope basic.Scope) error { func InitCpuFault(ctx context.Context, cpuTarget basic.Target) error { var ( - CpuFaultBurn = basic.Fault{TargetId: cpuTarget.ID, Name: "burn", NameCn: "cpu使用率", Description: "high cpu usage", DescriptionCn: "cpu使用率飙高,count 和 list 参数至少提供一个,都提供的时候,以 count 为准,忽略 list"} - CpuFaultLoad = basic.Fault{TargetId: cpuTarget.ID, Name: "load", NameCn: "cpu负载", Description: "high cpu usage", DescriptionCn: "cpu平均负载飙高"} + CpuFaultBurn = basic.Fault{TargetId: cpuTarget.ID, Name: "burn", NameCn: "cpu使用率", Description: "The CPU usage rate soars,provide at least one of the count and list parameters,when both are provided, count will prevail and list will be ignored.", DescriptionCn: "cpu使用率飙高,count和list参数至少提供一个,都提供的时候,以count为准,忽略list"} + CpuFaultLoad = basic.Fault{TargetId: cpuTarget.ID, Name: "load", NameCn: "cpu负载", Description: "High cpu usage", DescriptionCn: "cpu平均负载飙高"} ) if err := basic.InsertFault(ctx, &CpuFaultBurn); err != nil { return err @@ -185,22 +185,22 @@ func InitCpuFault(ctx context.Context, cpuTarget basic.Target) error { func InitCpuTargetArgsBurn(ctx context.Context, cpuFault basic.Fault) error { var ( - CpuArgsPercent = basic.Args{InjectId: cpuFault.ID, ExecType: ExecInject, Key: "percent", KeyCn: "使用率", Unit: "%", UnitCn: "%", Description: "target cpu usage", DescriptionCn: "目标cpu使用率", ValueType: "int", Required: true, ValueRule: "1-100"} - CpuArgsCount = basic.Args{InjectId: cpuFault.ID, ExecType: ExecInject, Key: "count", KeyCn: "核", Unit: "core", UnitCn: "大于等于0的整数,0表示全部核", DefaultValue: "0", Description: "number of faulty CPU cores", DescriptionCn: "故障cpu核数", ValueType: "int", ValueRule: ">=0"} - CpuArgsList = basic.Args{InjectId: cpuFault.ID, ExecType: ExecInject, Key: "list", KeyCn: "列表", Unit: "", UnitCn: "", Description: "cpu fault list", DescriptionCn: "故障cpu列表,逗号分隔的核编号列表,可以从/proc/cpuinfo确认", ValueType: "string"} + CpuArgsPercent = basic.Args{InjectId: cpuFault.ID, ExecType: ExecInject, Key: "percent", KeyCn: "使用率", Unit: "%", UnitCn: "%", Description: "Target cpu usage", DescriptionCn: "目标cpu使用率", ValueType: "int", Required: true, ValueRule: "1-100"} + CpuArgsCount = basic.Args{InjectId: cpuFault.ID, ExecType: ExecInject, Key: "count", KeyCn: "核数", Unit: "", UnitCn: "", DefaultValue: "0", Description: "Number of faulty CPU cores, 0 means all cores", DescriptionCn: "故障cpu核数,0表示全部核", ValueType: "int", ValueRule: ">=0"} + CpuArgsList = basic.Args{InjectId: cpuFault.ID, ExecType: ExecInject, Key: "list", KeyCn: "列表", Unit: "", UnitCn: "", Description: "Faulty cpu list, comma separated core number list, can be confirmed from /proc/cpuinfo", DescriptionCn: "故障cpu列表,逗号分隔的核编号列表,可以从/proc/cpuinfo确认", ValueType: "string"} ) return basic.InsertArgsMulti(ctx, []*basic.Args{&CpuArgsPercent, &CpuArgsCount, &CpuArgsList}) } func InitLoadTargetArgsLoad(ctx context.Context, loadFault basic.Fault) error { - var LoadArgsCount = basic.Args{InjectId: loadFault.ID, ExecType: ExecInject, Key: "count", KeyCn: "负载数", Unit: "", UnitCn: "", Description: "number of loads to add", DescriptionCn: "需要增加的负载数, 如果为0表示cpu核数的4倍", Required: true, ValueType: "int", ValueRule: ">=0"} + var LoadArgsCount = basic.Args{InjectId: loadFault.ID, ExecType: ExecInject, Key: "count", KeyCn: "负载数", Unit: "", UnitCn: "", Description: "Number of loads to add", DescriptionCn: "需要增加的负载数, 如果为0表示cpu核数的4倍", Required: true, ValueType: "int", ValueRule: ">=0"} return basic.InsertArgsMulti(ctx, []*basic.Args{&LoadArgsCount}) } func InitMemFault(ctx context.Context, memTarget basic.Target) error { var ( - MemFaultFill = basic.Fault{TargetId: memTarget.ID, Name: "fill", NameCn: "内存填充", Description: "memory usage soars", DescriptionCn: "内存使用率飙高, percent 和 bytes 参数都提供的时候,以 percent 为准,忽略 bytes"} - MemFaultOom = basic.Fault{TargetId: memTarget.ID, Name: "oom", NameCn: "内存oom", Description: "the system memory oom will cause the machine to hang up", DescriptionCn: "系统内存oom,会使机器宕机挂掉"} + MemFaultFill = basic.Fault{TargetId: memTarget.ID, Name: "fill", NameCn: "内存填充", Description: "Memory usage spikes, when percentage and bytes arguments are both provided, same as percentage, bytes ignored", DescriptionCn: "内存使用率飙高,percent和bytes参数都提供的时候,以percent为准,忽略bytes"} + MemFaultOom = basic.Fault{TargetId: memTarget.ID, Name: "oom", NameCn: "内存oom", Description: "The system memory oom will cause the machine to hang up", DescriptionCn: "系统内存oom,会使机器宕机挂掉"} ) if err := basic.InsertFault(ctx, &MemFaultFill); err != nil { @@ -218,20 +218,20 @@ func InitMemFault(ctx context.Context, memTarget basic.Target) error { func InitMemTargetArgsFill(ctx context.Context, memFault basic.Fault) error { var ( - MemArgsPercent = basic.Args{InjectId: memFault.ID, ExecType: ExecInject, Key: "percent", KeyCn: "内存使用率", Unit: "%", UnitCn: "%", Description: "target mem usage", DescriptionCn: "目标内存使用率", ValueType: "int", Required: true, ValueRule: "1-100"} - MemArgsBytes = basic.Args{InjectId: memFault.ID, ExecType: ExecInject, Key: "bytes", KeyCn: "填充量", Unit: "KB,MB,GB,TB", UnitCn: "KB,MB,GB,TB", Description: "memory fill", DescriptionCn: "内存填充量", ValueType: "string"} - MemArgsMode = basic.Args{InjectId: memFault.ID, ExecType: ExecInject, Key: "mode", KeyCn: "填充模式", Unit: "mode", UnitCn: "模式", Description: "memory fill mode", DescriptionCn: "内存填充模式", ValueType: "string", Required: true, ValueRule: "ram,cache"} + MemArgsPercent = basic.Args{InjectId: memFault.ID, ExecType: ExecInject, Key: "percent", KeyCn: "内存使用率", Unit: "%", UnitCn: "%", Description: "Target mem usage", DescriptionCn: "目标内存使用率", ValueType: "int", Required: true, ValueRule: "1-100"} + MemArgsBytes = basic.Args{InjectId: memFault.ID, ExecType: ExecInject, Key: "bytes", KeyCn: "填充量", Unit: "KB,MB,GB,TB", UnitCn: "KB,MB,GB,TB", Description: "Memory fill", DescriptionCn: "内存填充量", ValueType: "string"} + MemArgsMode = basic.Args{InjectId: memFault.ID, ExecType: ExecInject, Key: "mode", KeyCn: "填充模式", Unit: "mode", UnitCn: "模式", Description: "Memory filling mode, ram is the way to apply for process memory, cache is the way to use tmpfs", DescriptionCn: "内存填充模式,ram是使用进程内存申请的方式,cache是使用tmpfs的方式", ValueType: "string", Required: true, ValueRule: "ram,cache"} ) return basic.InsertArgsMulti(ctx, []*basic.Args{&MemArgsPercent, &MemArgsBytes, &MemArgsMode}) } func InitMemTargetArgsOom(ctx context.Context, memFault basic.Fault) error { - var MemArgsMode = basic.Args{InjectId: memFault.ID, ExecType: ExecInject, Key: "mode", KeyCn: "内存填充模式", Unit: "mode", UnitCn: "模式", DefaultValue: "cache", Description: "memory fill mode", DescriptionCn: "内存填充模式,ram是使用进程内存申请的方式,cache是使用tmpfs的方式", ValueType: "string", Required: true, ValueRule: "ram,cache"} + var MemArgsMode = basic.Args{InjectId: memFault.ID, ExecType: ExecInject, Key: "mode", KeyCn: "内存填充模式", Unit: "mode", UnitCn: "模式", DefaultValue: "cache", Description: "Memory filling mode, ram is the way to apply for process memory, cache is the way to use tmpfs", DescriptionCn: "内存填充模式,ram是使用进程内存申请的方式,cache是使用tmpfs的方式", ValueType: "string", Required: true, ValueRule: "ram,cache"} return basic.InsertArgsMulti(ctx, []*basic.Args{&MemArgsMode}) } func InitDiskFault(ctx context.Context, diskTarget basic.Target) error { - var DiskFaultFill = basic.Fault{TargetId: diskTarget.ID, Name: "fill", NameCn: "磁盘填充", Description: "disk usage soars", DescriptionCn: "磁盘使用率飙高,percent 和 bytes 参数都提供的时候,以 percent 为准,忽略 bytes"} + var DiskFaultFill = basic.Fault{TargetId: diskTarget.ID, Name: "fill", NameCn: "磁盘填充", Description: "The disk usage is so high, when both the percent and bytes parameters are provided, the percent will prevail and bytes will be ignored", DescriptionCn: "磁盘使用率飙高,percent和bytes参数都提供的时候,以percent为准,忽略bytes"} if err := basic.InsertFault(ctx, &DiskFaultFill); err != nil { return err } @@ -240,18 +240,18 @@ func InitDiskFault(ctx context.Context, diskTarget basic.Target) error { func InitDiskTargetArgsFill(ctx context.Context, diskFault basic.Fault) error { var ( - DiskArgsPercent = basic.Args{InjectId: diskFault.ID, ExecType: ExecInject, Key: "percent", KeyCn: "磁盘使用率", Unit: "%", UnitCn: "%", Description: "target disk usage", DescriptionCn: "目标磁盘使用率", ValueType: "int", Required: true, ValueRule: "1-100"} - DiskArgsBytes = basic.Args{InjectId: diskFault.ID, ExecType: ExecInject, Key: "bytes", KeyCn: "填充量", Unit: "KB,MB,GB,TB", UnitCn: "KB,MB,GB,TB", Description: "memory fill", DescriptionCn: "磁盘填充量", ValueType: "string"} - DiskArgsDir = basic.Args{InjectId: diskFault.ID, ExecType: ExecInject, Key: "dir", KeyCn: "目录", Unit: "target directory", UnitCn: "目标目录", DefaultValue: "/tmp", Description: "target population directory", DescriptionCn: "目标填充目录", ValueType: "string"} + DiskArgsPercent = basic.Args{InjectId: diskFault.ID, ExecType: ExecInject, Key: "percent", KeyCn: "磁盘使用率", Unit: "%", UnitCn: "%", Description: "Target disk usage", DescriptionCn: "目标磁盘使用率", ValueType: "int", Required: true, ValueRule: "1-100"} + DiskArgsBytes = basic.Args{InjectId: diskFault.ID, ExecType: ExecInject, Key: "bytes", KeyCn: "填充量", Unit: "KB,MB,GB,TB", UnitCn: "KB,MB,GB,TB", Description: "Memory fill", DescriptionCn: "磁盘填充量", ValueType: "string"} + DiskArgsDir = basic.Args{InjectId: diskFault.ID, ExecType: ExecInject, Key: "dir", KeyCn: "目录", Unit: "", UnitCn: "", DefaultValue: "/tmp", Description: "Target population directory", DescriptionCn: "目标填充目录", ValueType: "string"} ) return basic.InsertArgsMulti(ctx, []*basic.Args{&DiskArgsPercent, &DiskArgsBytes, &DiskArgsDir}) } func InitDiskioFault(ctx context.Context, diskioTarget basic.Target) error { var ( - DiskioFaultBurn = basic.Fault{TargetId: diskioTarget.ID, Name: "burn", NameCn: "磁盘IO高负载", Description: "disk IO soars", DescriptionCn: "磁盘IO飙高"} - DiskioFaultHang = basic.Fault{TargetId: diskioTarget.ID, Name: "hang", NameCn: "磁盘IO hang", Description: "the target process generates a disk IO hang", DescriptionCn: "目标进程产生磁盘IO hang; pid-list 和 key 参数至少提供一个,都提供的时候,以 pid-list 为准,忽略 key;此注入能力的原理是限制进程每秒只能进行 1 byte 大小的IO,所以对IO过小的进程影响不大"} - DiskioFaultLimit = basic.Fault{TargetId: diskioTarget.ID, Name: "limit", NameCn: "磁盘IO limit", Description: "target process generates disk IO limit", DescriptionCn: "目标进程产生磁盘IO limit; pid-list 和 key 参数都提供的时候,以 pid-list 为准,忽略 key;四个限制参数至少提供一个,多个限制是“与”的关系"} + DiskioFaultBurn = basic.Fault{TargetId: diskioTarget.ID, Name: "burn", NameCn: "磁盘IO高负载", Description: "Disk IO soars", DescriptionCn: "磁盘IO飙高"} + DiskioFaultHang = basic.Fault{TargetId: diskioTarget.ID, Name: "hang", NameCn: "磁盘IO hang", Description: "The target process generates a disk IO hang; provide at least one of the pid-list and key parameters. When both are provided, the pid-list will prevail and the key will be ignored; the principle of this injection capability is to limit the process to only 1byte of IO per second.Therefore, it has little impact on processes with too small IO", DescriptionCn: "目标进程产生磁盘IO hang;pid-list和key参数至少提供一个,都提供的时候,以pid-list为准,忽略key;此注入能力的原理是限制进程每秒只能进行1byte大小的IO,所以对IO过小的进程影响不大"} + DiskioFaultLimit = basic.Fault{TargetId: diskioTarget.ID, Name: "limit", NameCn: "磁盘IO limit", Description: "The target process generates a disk IO limit; when both pid-list and key parameters are provided, the pid-list shall prevail and the key shall be ignored; at least one of the four limit parameters must be provided, and multiple limits are in an \"AND\" relationship", DescriptionCn: "目标进程产生磁盘IO limit;pid-list和key参数都提供的时候,以pid-list为准,忽略key;四个限制参数至少提供一个,多个限制是“与”的关系"} ) if err := basic.InsertFault(ctx, &DiskioFaultBurn); err != nil { return err @@ -274,46 +274,46 @@ func InitDiskioFault(ctx context.Context, diskioTarget basic.Target) error { func InitDiskioTargetArgsBurn(ctx context.Context, diskioFault basic.Fault) error { var ( - DiskioArgsDir = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "dir", KeyCn: "目录", Unit: "", UnitCn: "", DefaultValue: "/tmp", Description: "target directory for high IO operations", DescriptionCn: "进行高IO操作的目标目录", ValueType: "string", Required: true} + DiskioArgsDir = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "dir", KeyCn: "目录", Unit: "", UnitCn: "", DefaultValue: "/tmp", Description: "Target directory for high IO operations", DescriptionCn: "进行高IO操作的目标目录", ValueType: "string", Required: true} DiskioArgsMode = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "mode", KeyCn: "IO模式", Unit: "", UnitCn: "", DefaultValue: "read", Description: "IO mode", DescriptionCn: "IO模式", ValueType: "string", Required: true, ValueRule: "read,write"} - DiskioArgsBlock = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "block", KeyCn: "IO块", Unit: "KB,MB", UnitCn: "KB,MB", DefaultValue: "10MB", Description: "the block size of a single IO", DescriptionCn: "单次IO的块大小, 范围为1K-1024M", ValueType: "string", Required: true, ValueRule: "1-1024"} + DiskioArgsBlock = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "block", KeyCn: "IO块", Unit: "KB,MB", UnitCn: "KB,MB", DefaultValue: "10MB", Description: "The block size of a single IO, ranging from 1K-1024M", DescriptionCn: "单次IO的块大小,范围为1K-1024M", ValueType: "string", Required: true, ValueRule: "1-1024"} ) return basic.InsertArgsMulti(ctx, []*basic.Args{&DiskioArgsDir, &DiskioArgsMode, &DiskioArgsBlock}) } func InitDiskioTargetArgsHang(ctx context.Context, diskioFault basic.Fault) error { var ( - DiskioArgsDevList = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "dev-list", KeyCn: "设备列表", Unit: "", UnitCn: "", Description: "target disk device list", DescriptionCn: "目标磁盘设备列表,使用命令lsblk -a | grep disk获取目标设备的主备设备号。比如:8:0", ValueType: "stringlist"} - DiskioArgsPidList = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "pid-list", KeyCn: "进程pid列表", Unit: "", UnitCn: "", Description: "affected process pid list", DescriptionCn: "受影响的进程pid列表,比如:7850,7690", ValueType: "stringlist"} - DiskioArgsKey = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "key", KeyCn: "关键词", Unit: "", UnitCn: "", Description: "keyword used to filter affected processes", DescriptionCn: "用来筛选受影响进程的关键词,会使用ps -ef | grep [key]来筛选", ValueType: "string"} - DiskioArgsMode = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "mode", KeyCn: "IO模式", Unit: "mode", UnitCn: "模式", DefaultValue: "all", Description: "affected IO operation", DescriptionCn: "受影响的IO操作", ValueType: "string", ValueRule: "all,read,write"} + DiskioArgsDevList = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "dev-list", KeyCn: "设备列表", Unit: "", UnitCn: "", Description: "Target disk device list, use the command lsblk -a | grep disk to obtain the primary and secondary device numbers of the target device, such as 8:0", DescriptionCn: "目标磁盘设备列表,使用命令lsblk -a | grep disk获取目标设备的主备设备号,比如8:0", ValueType: "stringlist"} + DiskioArgsPidList = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "pid-list", KeyCn: "进程pid列表", Unit: "", UnitCn: "", Description: "Affected process pid list, for example: 7850, 7690", DescriptionCn: "受影响的进程pid列表,比如:7850,7690", ValueType: "stringlist"} + DiskioArgsKey = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "key", KeyCn: "关键词", Unit: "", UnitCn: "", Description: "keywords used to filter affected processes will be filtered using ps -ef | grep [key]", DescriptionCn: "用来筛选受影响进程的关键词,会使用ps -ef | grep [key]来筛选", ValueType: "string"} + DiskioArgsMode = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "mode", KeyCn: "IO模式", Unit: "mode", UnitCn: "模式", DefaultValue: "all", Description: "Affected IO operation", DescriptionCn: "受影响的IO操作", ValueType: "string", ValueRule: "all,read,write"} ) return basic.InsertArgsMulti(ctx, []*basic.Args{&DiskioArgsDevList, &DiskioArgsPidList, &DiskioArgsKey, &DiskioArgsMode}) } func InitDiskioTargetArgsLimit(ctx context.Context, diskioFault basic.Fault) error { var ( - DiskioArgsDevList = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "dev-list", KeyCn: "设备列表", Unit: "", UnitCn: "", Description: "target disk device list", DescriptionCn: "目标磁盘设备列表,使用命令lsblk -a | grep disk获取目标设备的主备设备号。比如:8:0", ValueType: "stringlist"} - DiskioArgsPidList = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "pid-list", KeyCn: "进程pid列表", Unit: "", UnitCn: "", Description: "affected process pid list", DescriptionCn: "受影响的进程pid列表,比如:7850,7690", ValueType: "stringlist"} - DiskioArgsKey = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "key", KeyCn: "关键词", Unit: "", UnitCn: "", Description: "keyword used to filter affected processes", DescriptionCn: "用来筛选受影响进程的关键词,会使用ps -ef | grep [key]来筛选", ValueType: "string"} - DiskioArgsReadBytes = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "read-bytes", KeyCn: "读字节数", Unit: "B,KB,MB,GB,TB", UnitCn: "B,KB,MB,GB,TB", Description: "number of bytes that can be read per second", DescriptionCn: "每秒能读的字节数", ValueType: "string"} - DiskioArgsWriteBytes = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "write-bytes", KeyCn: "写字节数", Unit: "B,KB,MB,GB,TB", UnitCn: "B,KB,MB,GB,TB", Description: "number of bytes that can be written per second", DescriptionCn: "每秒能写的字节数", ValueType: "string"} - DiskioArgsReadIO = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "read-io", KeyCn: "读IO次数", Unit: "", UnitCn: "", Description: "number of IO operations that can be read per second", DescriptionCn: "每秒能读的IO次数", ValueType: "int", ValueRule: ">0"} - DiskioArgsWriteIO = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "write-io", KeyCn: "写IO次数", Unit: "", UnitCn: "", Description: "number of IO operations that can be written per second", DescriptionCn: "每秒能写的IO次数", ValueType: "int", ValueRule: ">0"} + DiskioArgsDevList = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "dev-list", KeyCn: "设备列表", Unit: "", UnitCn: "", Description: "Target disk device list, use the command lsblk -a | grep disk to obtain the primary and secondary device numbers of the target device, such as 8:0", DescriptionCn: "目标磁盘设备列表,使用命令lsblk -a | grep disk获取目标设备的主备设备号,比如8:0", ValueType: "stringlist"} + DiskioArgsPidList = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "pid-list", KeyCn: "进程pid列表", Unit: "", UnitCn: "", Description: "Affected process pid list, such as 7850, 7690", DescriptionCn: "受影响的进程pid列表,比如7850,7690", ValueType: "stringlist"} + DiskioArgsKey = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "key", KeyCn: "关键词", Unit: "", UnitCn: "", Description: "Keywords used to filter affected processes will be filtered using ps -ef | grep [key]", DescriptionCn: "用来筛选受影响进程的关键词,会使用ps -ef | grep [key]来筛选", ValueType: "string"} + DiskioArgsReadBytes = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "read-bytes", KeyCn: "读字节数", Unit: "B,KB,MB,GB,TB", UnitCn: "B,KB,MB,GB,TB", Description: "Number of bytes that can be read per second", DescriptionCn: "每秒能读的字节数", ValueType: "string"} + DiskioArgsWriteBytes = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "write-bytes", KeyCn: "写字节数", Unit: "B,KB,MB,GB,TB", UnitCn: "B,KB,MB,GB,TB", Description: "Number of bytes that can be written per second", DescriptionCn: "每秒能写的字节数", ValueType: "string"} + DiskioArgsReadIO = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "read-io", KeyCn: "读IO次数", Unit: "", UnitCn: "", Description: "Number of IO operations that can be read per second", DescriptionCn: "每秒能读的IO次数", ValueType: "int", ValueRule: ">0"} + DiskioArgsWriteIO = basic.Args{InjectId: diskioFault.ID, ExecType: ExecInject, Key: "write-io", KeyCn: "写IO次数", Unit: "", UnitCn: "", Description: "Number of IO operations that can be written per second", DescriptionCn: "每秒能写的IO次数", ValueType: "int", ValueRule: ">0"} ) return basic.InsertArgsMulti(ctx, []*basic.Args{&DiskioArgsDevList, &DiskioArgsPidList, &DiskioArgsKey, &DiskioArgsReadBytes, &DiskioArgsWriteBytes, &DiskioArgsReadIO, &DiskioArgsWriteIO}) } func InitNetworkFault(ctx context.Context, networkTarget basic.Target) error { var ( - NetworkFaultOccupy = basic.Fault{TargetId: networkTarget.ID, Name: "occupy", NameCn: "端口占用", Description: "kill the service of the target port and occupy this port", DescriptionCn: "把目标端口的服务kill掉并把这个端口占用掉"} - NetworkFaultLimit = basic.Fault{TargetId: networkTarget.ID, Name: "limit", NameCn: "带宽限制", Description: "bandwidth limit for network packet injection in the outbound direction from the failed machine", DescriptionCn: "对从故障机器流出方向的网络数据包注入带宽限制, interface 必须提供,数据包筛选参数可以选择性提供,“与”的关系"} - NetworkFaultDelay = basic.Fault{TargetId: networkTarget.ID, Name: "delay", NameCn: "网络延迟", Description: "network packet injection delay in outbound direction from the failed machine", DescriptionCn: "从故障机器流出方向的网络数据包注入延迟;interface 必须提供,数据包筛选参数可以选择性提供,“与”的关系"} - NetworkFaultLoss = basic.Fault{TargetId: networkTarget.ID, Name: "loss", NameCn: "网络丢包", Description: "network packet injection in outbound direction from faulty machine drops packets", DescriptionCn: "从故障机器流出方向的网络数据包注入丢包;interface 必须提供,数据包筛选参数可以选择性提供,“与”的关系"} - NetworkFaultCorrupt = basic.Fault{TargetId: networkTarget.ID, Name: "corrupt", NameCn: "网络包损坏", Description: "inject packet corruption on network packets in the outbound direction from the failed machine", DescriptionCn: "对从故障机器流出方向的网络数据包注入包损坏;interface 必须提供,数据包筛选参数可以选择性提供,“与”的关系"} - - NetworkFaultDuplicate = basic.Fault{TargetId: networkTarget.ID, Name: "duplicate", NameCn: "网络包重复", Description: "repeat for network packet injection packets in the outbound direction from the failed machine", DescriptionCn: "对从故障机器流出方向的网络数据包注入包重复;interface 必须提供,数据包筛选参数可以选择性提供,“与”的关系"} - NetworkFaultReorder = basic.Fault{TargetId: networkTarget.ID, Name: "reorder", NameCn: "网络包乱序", Description: "inject out-of-sequence packets into network packets in the outflow direction from the faulty machine", DescriptionCn: "对从故障机器流出方向的网络数据包注入包乱序;interface 必须提供,数据包筛选参数可以选择性提供,“与”的关系"} + NetworkFaultOccupy = basic.Fault{TargetId: networkTarget.ID, Name: "occupy", NameCn: "端口占用", Description: "Kill the service on the target port and occupy this port", DescriptionCn: "把目标端口的服务kill掉并把这个端口占用掉"} + NetworkFaultLimit = basic.Fault{TargetId: networkTarget.ID, Name: "limit", NameCn: "带宽限制", Description: "To inject bandwidth restrictions on network packets in the outflow direction from the faulty machine, the interface must be provided. The packet filtering parameters can be optionally provided. The relationship between \"and\"", DescriptionCn: "对从故障机器流出方向的网络数据包注入带宽限制,interface必须提供,数据包筛选参数可以选择性提供,“与”的关系"} + NetworkFaultDelay = basic.Fault{TargetId: networkTarget.ID, Name: "delay", NameCn: "网络延迟", Description: "Network packet injection delay in the outflow direction from the faulty machine; interface must be provided, packet filtering parameters can be optionally provided, the relationship between \"and\"", DescriptionCn: "从故障机器流出方向的网络数据包注入延迟;interface必须提供,数据包筛选参数可以选择性提供,“与”的关系"} + NetworkFaultLoss = basic.Fault{TargetId: networkTarget.ID, Name: "loss", NameCn: "网络丢包", Description: "Network data packets in the outflow direction from the faulty machine are injected into packet loss; interface must be provided, and packet filtering parameters can be optionally provided, the relationship between \"and\"", DescriptionCn: "从故障机器流出方向的网络数据包注入丢包;interface 必须提供,数据包筛选参数可以选择性提供,“与”的关系"} + NetworkFaultCorrupt = basic.Fault{TargetId: networkTarget.ID, Name: "corrupt", NameCn: "网络包损坏", Description: "Inject packet damage into the network data packets flowing out from the faulty machine; the interface must be provided, and the packet filtering parameters can be optionally provided, the relationship between \"and\"", DescriptionCn: "对从故障机器流出方向的网络数据包注入包损坏;interface必须提供,数据包筛选参数可以选择性提供,“与”的关系"} + + NetworkFaultDuplicate = basic.Fault{TargetId: networkTarget.ID, Name: "duplicate", NameCn: "网络包重复", Description: "Repeat for network packet injection packets in the outflow direction from the faulty machine; interface must be provided, packet filtering parameters can be optionally provided, \"relationship with\"", DescriptionCn: "对从故障机器流出方向的网络数据包注入包重复;interface必须提供,数据包筛选参数可以选择性提供,“与”的关系"} + NetworkFaultReorder = basic.Fault{TargetId: networkTarget.ID, Name: "reorder", NameCn: "网络包乱序", Description: "Inject packet reordering into network data packets flowing out from the faulty machine; the interface must be provided, and the packet filtering parameters can be optionally provided, the relationship between \"and\"", DescriptionCn: "对从故障机器流出方向的网络数据包注入包乱序;interface必须提供,数据包筛选参数可以选择性提供,“与”的关系"} ) if err := basic.InsertFault(ctx, &NetworkFaultOccupy); err != nil { @@ -360,13 +360,13 @@ func InitNetworkFault(ctx context.Context, networkTarget basic.Target) error { func getNetworkCommonFilterParameters(fault basic.Fault) []*basic.Args { var ( - NetworkArgsInterface = basic.Args{InjectId: fault.ID, ExecType: ExecInject, Key: "interface", KeyCn: "网卡", Description: "network interface;the network card included in the faulty machine, such as: eth0", DescriptionCn: "网卡;故障机器包含的网卡,比如:eth0", Required: true, ValueType: "string"} - NetworkArgsDstIP = basic.Args{InjectId: fault.ID, ExecType: ExecInject, Key: "dst-ip", KeyCn: "目标ip列表", Description: "packet filtering parameter: destination IP list;for example: 1.2.3.4, 2.3.4.5, 192.168.1.1/24", DescriptionCn: "数据包筛选参数:目标ip列表;如:1.2.3.4,2.3.4.5,192.168.1.1/24", ValueType: "stringlist"} - NetworkArgsSrcIP = basic.Args{InjectId: fault.ID, ExecType: ExecInject, Key: "src-ip", KeyCn: "数据包筛选参数:源ip列表", Description: "packet filtering parameter: source IP list;for example: 1.2.3.4,2.3.4.5,192.168.1.1/24", DescriptionCn: "数据包筛选参数:源ip列表;如:1.2.3.4,2.3.4.5,192.168.1.1/24", ValueType: "stringlist"} - NetworkArgsDstPort = basic.Args{InjectId: fault.ID, ExecType: ExecInject, Key: "dst-port", KeyCn: "数据包筛选参数:目标端口列表", Description: "packet filtering parameter: destination port list;for example: 8080-8090,8095,9099", DescriptionCn: "数据包筛选参数:目标端口列表;;如:1.2.3.4,2.3.4.5,192.168.1.1/24", ValueType: "stringlist"} - NetworkArgsSrcPort = basic.Args{InjectId: fault.ID, ExecType: ExecInject, Key: "src-port", KeyCn: "数据包筛选参数:源端口列表", Description: "packet filtering parameter: source port list;for example: 8080-8090,8095,9099", DescriptionCn: "数据包筛选参数:源端口列表;如:1.2.3.4,2.3.4.5,192.168.1.1/24", ValueType: "stringlist"} - NetworkArgsMode = basic.Args{InjectId: fault.ID, ExecType: ExecInject, Key: "mode", KeyCn: "数据", Unit: "normal: inject fault to selected targets, exclude: do not inject fault to selected targets", UnitCn: "normal:对选中的目标注入故障 exclude:对选中的目标不注入故障", DefaultValue: "normal", Description: "packet filtering mode", DescriptionCn: "数据包筛选模式", ValueType: "string"} - NetworkArgsForce = basic.Args{InjectId: fault.ID, ExecType: ExecInject, Key: "force", KeyCn: "是否强制覆盖", DefaultValue: "false", Description: "whether to force overwrite", DescriptionCn: "是否强制覆盖", ValueType: "bool", ValueRule: "true,false"} + NetworkArgsInterface = basic.Args{InjectId: fault.ID, ExecType: ExecInject, Key: "interface", KeyCn: "网卡", Description: "The network card included in the faulty machine, such as eth0", DescriptionCn: "故障机器包含的网卡,比如eth0", Required: true, ValueType: "string"} + NetworkArgsDstIP = basic.Args{InjectId: fault.ID, ExecType: ExecInject, Key: "dst-ip", KeyCn: "目标ip列表", Description: "Target IP list, such as: 1.2.3.4, 2.3.4.5, 192.168.1.1/24", DescriptionCn: "目标ip列表,比如1.2.3.4,2.3.4.5,192.168.1.1/24", ValueType: "stringlist"} + NetworkArgsSrcIP = basic.Args{InjectId: fault.ID, ExecType: ExecInject, Key: "src-ip", KeyCn: "数据包筛选参数:源ip列表", Description: "Source IP list, for example: 1.2.3.4,2.3.4.5,192.168.1.1/24", DescriptionCn: "源ip列表,比如1.2.3.4,2.3.4.5,192.168.1.1/24", ValueType: "stringlist"} + NetworkArgsDstPort = basic.Args{InjectId: fault.ID, ExecType: ExecInject, Key: "dst-port", KeyCn: "数据包筛选参数:目标端口列表", Description: "Target port list, for example: 8080-8090,8095,9099", DescriptionCn: "目标端口列表,比如8080-8090,8095,9099", ValueType: "stringlist"} + NetworkArgsSrcPort = basic.Args{InjectId: fault.ID, ExecType: ExecInject, Key: "src-port", KeyCn: "数据包筛选参数:源端口列表", Description: "Source port list, such as 8080-8090,8095,9099", DescriptionCn: "源端口列表,比如8080-8090,8095,9099", ValueType: "stringlist"} + NetworkArgsMode = basic.Args{InjectId: fault.ID, ExecType: ExecInject, Key: "mode", KeyCn: "数据包筛选模式", Unit: "", UnitCn: "", DefaultValue: "normal", Description: "normal: inject fault to selected targets, exclude: do not inject fault to selected targets", DescriptionCn: "normal:对选中的目标注入故障,exclude:对选中的目标不注入故障", ValueType: "string", ValueRule: "normal,exclude"} + NetworkArgsForce = basic.Args{InjectId: fault.ID, ExecType: ExecInject, Key: "force", KeyCn: "是否强制覆盖", DefaultValue: "false", Description: "Whether to force overwrite", DescriptionCn: "是否强制覆盖", ValueType: "bool", ValueRule: "true,false"} ) return []*basic.Args{&NetworkArgsInterface, &NetworkArgsDstIP, &NetworkArgsSrcIP, &NetworkArgsDstPort, &NetworkArgsSrcPort, &NetworkArgsMode, &NetworkArgsForce} } @@ -374,7 +374,7 @@ func getNetworkCommonFilterParameters(fault basic.Fault) []*basic.Args { func InitNetworkTargetArgsOccupy(ctx context.Context, networkFault basic.Fault) error { var ( NetworkArgsPort = basic.Args{InjectId: networkFault.ID, ExecType: ExecInject, Key: "port", KeyCn: "端口", Description: "target port", DescriptionCn: "目标端口", ValueType: "int"} - NetworkArgsProtocol = basic.Args{InjectId: networkFault.ID, ExecType: ExecInject, Key: "protocol", KeyCn: "协议", Unit: "tcp,udp,tcp6,udp6", UnitCn: "tcp,udp,tcp6,udp6", DefaultValue: "tcp", Description: "target protocol", DescriptionCn: "目标协议", ValueType: "string"} + NetworkArgsProtocol = basic.Args{InjectId: networkFault.ID, ExecType: ExecInject, Key: "protocol", KeyCn: "协议", DefaultValue: "tcp", Description: "target protocol", DescriptionCn: "目标协议", ValueType: "string", ValueRule: "tcp,udp,tcp6,udp6"} NetworkArgsRecoverCmd = basic.Args{InjectId: networkFault.ID, ExecType: ExecInject, Key: "recover-cmd", KeyCn: "恢复命令", Description: "resume command, it will be executed last when resuming operation", DescriptionCn: "恢复命令,恢复操作时会最后执行", ValueType: "string"} ) return basic.InsertArgsMulti(ctx, []*basic.Args{&NetworkArgsPort, &NetworkArgsProtocol, &NetworkArgsRecoverCmd}) @@ -382,7 +382,7 @@ func InitNetworkTargetArgsOccupy(ctx context.Context, networkFault basic.Fault) func InitNetworkTargetArgsLimit(ctx context.Context, networkFault basic.Fault) error { var ( - NetworkArgsRate = basic.Args{InjectId: networkFault.ID, ExecType: ExecInject, Key: "rate", KeyCn: "带宽限制", Unit: "bit,kbit,mbit,gbit,tbit", UnitCn: "bit,kbit,mbit,gbit,tbit", Description: "network bandwidth limit per second", DescriptionCn: "每秒的网络带宽限制", ValueType: "int", Required: true} + NetworkArgsRate = basic.Args{InjectId: networkFault.ID, ExecType: ExecInject, Key: "rate", KeyCn: "每秒的网络带宽限制", Unit: "bit,kbit,mbit,gbit,tbit", UnitCn: "bit,kbit,mbit,gbit,tbit", Description: "Network bandwidth limit per second", DescriptionCn: "每秒的网络带宽限制", ValueType: "int", Required: true} ) argList := []*basic.Args{&NetworkArgsRate} argList = append(argList, getNetworkCommonFilterParameters(networkFault)...) @@ -391,8 +391,8 @@ func InitNetworkTargetArgsLimit(ctx context.Context, networkFault basic.Fault) e func InitNetworkTargetArgsDelay(ctx context.Context, networkFault basic.Fault) error { var ( - NetworkArgsLatency = basic.Args{InjectId: networkFault.ID, ExecType: ExecInject, Key: "latency", KeyCn: "延迟时间", Unit: "us,ms,s", UnitCn: "us,ms,s", Description: "delay", DescriptionCn: "延迟时间", ValueType: "int", Required: true} - NetworkArgsJitter = basic.Args{InjectId: networkFault.ID, ExecType: ExecInject, Key: "jitter", KeyCn: "抖动值", Unit: "us,ms,s", UnitCn: "us,ms,s", Description: "jitter value, the fluctuation range of each delay", DescriptionCn: "抖动值,每次延迟的波动范围", DefaultValue: "0", ValueType: "int", Required: true} + NetworkArgsLatency = basic.Args{InjectId: networkFault.ID, ExecType: ExecInject, Key: "latency", KeyCn: "延迟时间", Unit: "us,ms,s", UnitCn: "us,ms,s", Description: "Delay time", DescriptionCn: "延迟时间", ValueType: "int", Required: true} + NetworkArgsJitter = basic.Args{InjectId: networkFault.ID, ExecType: ExecInject, Key: "jitter", KeyCn: "抖动值", Unit: "us,ms,s", UnitCn: "us,ms,s", Description: "Jitter value, the fluctuation range of each delay", DescriptionCn: "抖动值,每次延迟的波动范围", DefaultValue: "0", ValueType: "int", Required: true} ) argList := []*basic.Args{&NetworkArgsLatency, &NetworkArgsJitter} @@ -401,7 +401,7 @@ func InitNetworkTargetArgsDelay(ctx context.Context, networkFault basic.Fault) e } func InitNetworkTargetArgsLoss(ctx context.Context, networkFault basic.Fault) error { - var NetworkArgsPercent = basic.Args{InjectId: networkFault.ID, ExecType: ExecInject, Key: "percent", KeyCn: "丢包率", Description: "packet loss rate", DescriptionCn: "丢包率", ValueType: "int", Required: true, ValueRule: "1-100"} + var NetworkArgsPercent = basic.Args{InjectId: networkFault.ID, ExecType: ExecInject, Key: "percent", KeyCn: "丢包率", Description: "Packet loss rate", DescriptionCn: "丢包率", ValueType: "int", Required: true, ValueRule: "1-100"} argList := []*basic.Args{&NetworkArgsPercent} argList = append(argList, getNetworkCommonFilterParameters(networkFault)...) @@ -409,7 +409,7 @@ func InitNetworkTargetArgsLoss(ctx context.Context, networkFault basic.Fault) er } func InitNetworkTargetArgsCorrupt(ctx context.Context, networkFault basic.Fault) error { - var NetworkArgsPercent = basic.Args{InjectId: networkFault.ID, ExecType: ExecInject, Key: "percent", KeyCn: "包损坏率", Description: "packet loss rate", DescriptionCn: "包损坏率", ValueType: "int", Required: true, ValueRule: "1-100"} + var NetworkArgsPercent = basic.Args{InjectId: networkFault.ID, ExecType: ExecInject, Key: "percent", KeyCn: "包损坏率", Description: "Packet loss rate", DescriptionCn: "包损坏率", ValueType: "int", Required: true, ValueRule: "1-100"} argList := []*basic.Args{&NetworkArgsPercent} argList = append(argList, getNetworkCommonFilterParameters(networkFault)...) @@ -417,7 +417,7 @@ func InitNetworkTargetArgsCorrupt(ctx context.Context, networkFault basic.Fault) } func InitNetworkTargetArgsDuplicate(ctx context.Context, networkFault basic.Fault) error { - var NetworkArgsPercent = basic.Args{InjectId: networkFault.ID, ExecType: ExecInject, Key: "percent", KeyCn: "丢包率", Description: "packet loss rate", DescriptionCn: "丢包率", ValueType: "int", Required: true, ValueRule: "1-100"} + var NetworkArgsPercent = basic.Args{InjectId: networkFault.ID, ExecType: ExecInject, Key: "percent", KeyCn: "包重复率", Description: "packet loss rate", DescriptionCn: "丢包率", ValueType: "int", Required: true, ValueRule: "1-100"} argList := []*basic.Args{&NetworkArgsPercent} argList = append(argList, getNetworkCommonFilterParameters(networkFault)...) @@ -426,8 +426,8 @@ func InitNetworkTargetArgsDuplicate(ctx context.Context, networkFault basic.Faul func InitNetworkTargetArgsReorder(ctx context.Context, networkFault basic.Fault) error { var ( - NetworkArgsLatency = basic.Args{InjectId: networkFault.ID, ExecType: ExecInject, Key: "latency", KeyCn: "延迟时间", Unit: "s,ms,us", UnitCn: "s,ms,us", DefaultValue: "1s", Description: "delay", DescriptionCn: "延迟时间", ValueType: "int", Required: true} - NetworkArgsGap = basic.Args{InjectId: networkFault.ID, ExecType: ExecInject, Key: "gap", KeyCn: "KeyCn", DefaultValue: "3", Description: "select the interval, for example, if the gap is 3, it means that the packets with serial numbers 1, 3, 6, 9, etc. will not be delayed, and the rest of the packets will be delayed", DescriptionCn: "选中间隔,比如gap为3表示序号为1、3、6、9等的包不延迟,其余的包会延迟", ValueType: "int", ValueRule: ">0"} + NetworkArgsLatency = basic.Args{InjectId: networkFault.ID, ExecType: ExecInject, Key: "latency", KeyCn: "包延迟", Unit: "us,ms,s", UnitCn: "us,ms,s", DefaultValue: "1s", Description: "delay", DescriptionCn: "延迟时间", ValueType: "int", Required: true} + NetworkArgsGap = basic.Args{InjectId: networkFault.ID, ExecType: ExecInject, Key: "gap", KeyCn: "KeyCn", DefaultValue: "3", Description: "Select the interval. For example, a gap of 3 means that packets with serial numbers 1, 3, 6, 9, etc. will not be delayed, and the remaining packets will be delayed", DescriptionCn: "选中间隔,比如gap为3表示序号为1、3、6、9等的包不延迟,其余的包会延迟", ValueType: "int", ValueRule: ">0"} ) argList := []*basic.Args{&NetworkArgsLatency, &NetworkArgsGap} argList = append(argList, getNetworkCommonFilterParameters(networkFault)...) @@ -436,9 +436,8 @@ func InitNetworkTargetArgsReorder(ctx context.Context, networkFault basic.Fault) func InitProcessFault(ctx context.Context, processTarget basic.Target) error { var ( - processFaultKill = basic.Fault{TargetId: processTarget.ID, Name: "kill", NameCn: "杀进程", Description: "kill the target process", DescriptionCn: "把目标进程杀掉;pid 和 key 参数至少提供一个,都提供的时候,以 pid 为准,忽略 key"} - - processFaultStop = basic.Fault{TargetId: processTarget.ID, Name: "stop", NameCn: "停止进程", Description: "stop target process", DescriptionCn: "停止目标进程; pid 和 key 参数至少提供一个,都提供的时候,以 pid 为准,忽略 key"} + processFaultKill = basic.Fault{TargetId: processTarget.ID, Name: "kill", NameCn: "杀进程", Description: "To kill the target process, provide at least one of the pid and key parameters. When both are provided, the pid will prevail and the key will be ignored.", DescriptionCn: "把目标进程杀掉,pid和key参数至少提供一个,都提供的时候,以pid为准,忽略key"} + processFaultStop = basic.Fault{TargetId: processTarget.ID, Name: "stop", NameCn: "停止进程", Description: "Stop the target process. Provide at least one of the pid and key parameters. When both are provided, the pid will prevail and the key will be ignored.", DescriptionCn: "停止目标进程,pid和key参数至少提供一个,都提供的时候,以pid为准,忽略key"} ) if err := basic.InsertFault(ctx, &processFaultKill); err != nil { return err @@ -456,7 +455,7 @@ func InitProcessFault(ctx context.Context, processTarget basic.Target) error { func InitProcessTargetArgsKill(ctx context.Context, processFault basic.Fault) error { var ( ProcessArgsKey = basic.Args{InjectId: processFault.ID, ExecType: ExecInject, Key: "key", KeyCn: "关键词", Description: "keywords used to filter affected processes; Will use ps -ef | grep [key] to filter", DescriptionCn: "用来筛选受影响进程的关键词;会使用ps -ef | grep [key]来筛选", ValueType: "string"} - ProcessArgsPid = basic.Args{InjectId: processFault.ID, ExecType: ExecInject, Key: "pid", KeyCn: "进程", Description: "the pid of the living process", DescriptionCn: "存活进程的pid", ValueType: "int"} + ProcessArgsPid = basic.Args{InjectId: processFault.ID, ExecType: ExecInject, Key: "pid", KeyCn: "进程pid", Description: "the pid of the living process", DescriptionCn: "存活进程的pid", ValueType: "int"} ProcessArgsSignal = basic.Args{InjectId: processFault.ID, ExecType: ExecInject, Key: "signal", KeyCn: "信号", DefaultValue: "9", Description: "the signal sent to the process;consistent with the signal value supported by the kill command", DescriptionCn: "对进程发送的信号;和kill命令支持的信号数值一致", ValueType: "int"} ProcessArgsRecoverCmd = basic.Args{InjectId: processFault.ID, ExecType: ExecInject, Key: "recover-cmd", KeyCn: "恢复命令", Description: "resume command, it will be executed last when resuming operation", DescriptionCn: "恢复命令,恢复操作时会最后执行", ValueType: "string"} ) @@ -465,19 +464,19 @@ func InitProcessTargetArgsKill(ctx context.Context, processFault basic.Fault) er func InitProcessTargetArgsStop(ctx context.Context, processFault basic.Fault) error { var ( - ProcessArgsKey = basic.Args{InjectId: processFault.ID, ExecType: ExecInject, Key: "key", KeyCn: "关键词", Description: "keywords used to filter affected processes; will use ps -ef | grep [key] to filter", DescriptionCn: "用来筛选受影响进程的关键词; 会使用ps -ef | grep [key]来筛选", ValueType: "string"} - ProcessArgsPid = basic.Args{InjectId: processFault.ID, ExecType: ExecInject, Key: "pid", KeyCn: "进程", Description: "the pid of the living process", DescriptionCn: "存活进程的pid", ValueType: "int"} + ProcessArgsKey = basic.Args{InjectId: processFault.ID, ExecType: ExecInject, Key: "key", KeyCn: "关键词", Description: "Keywords used to filter affected processes, will use ps -ef | grep [key] to filter", DescriptionCn: "用来筛选受影响进程的关键词;会使用ps -ef | grep [key]来筛选", ValueType: "string"} + ProcessArgsPid = basic.Args{InjectId: processFault.ID, ExecType: ExecInject, Key: "pid", KeyCn: "进程", Description: "The pid of the living process", DescriptionCn: "存活进程的pid", ValueType: "int"} ) return basic.InsertArgsMulti(ctx, []*basic.Args{&ProcessArgsKey, &ProcessArgsPid}) } func InitFileFault(ctx context.Context, fileTarget basic.Target) error { var ( - fileFaultChmod = basic.Fault{TargetId: fileTarget.ID, Name: "chmod", NameCn: "篡改权限", Description: "file access permissions have been modified", DescriptionCn: "文件访问权限被修改"} - fileFaultDelete = basic.Fault{TargetId: fileTarget.ID, Name: "del", NameCn: "删除文件", Description: "delete target file", DescriptionCn: "删除目标文件"} - fileFaultAppend = basic.Fault{TargetId: fileTarget.ID, Name: "append", NameCn: "追加文件", Description: "append content to the target file, often used for exception log injection", DescriptionCn: "对目标文件追加内容,常用于异常日志注入"} - fileFaultAdd = basic.Fault{TargetId: fileTarget.ID, Name: "add", NameCn: "增加文件", Description: "add file", DescriptionCn: "增加文件"} - fileFaultMv = basic.Fault{TargetId: fileTarget.ID, Name: "mv", NameCn: "移动文件", Description: "move file", DescriptionCn: "移动文件"} + fileFaultChmod = basic.Fault{TargetId: fileTarget.ID, Name: "chmod", NameCn: "篡改权限", Description: "File access permissions have been modified", DescriptionCn: "文件访问权限被修改"} + fileFaultDelete = basic.Fault{TargetId: fileTarget.ID, Name: "del", NameCn: "删除文件", Description: "Delete target file", DescriptionCn: "删除目标文件"} + fileFaultAppend = basic.Fault{TargetId: fileTarget.ID, Name: "append", NameCn: "追加文件", Description: "Append content to the target file, often used for exception log injection", DescriptionCn: "对目标文件追加内容,常用于异常日志注入"} + fileFaultAdd = basic.Fault{TargetId: fileTarget.ID, Name: "add", NameCn: "增加文件", Description: "Add file", DescriptionCn: "增加文件"} + fileFaultMv = basic.Fault{TargetId: fileTarget.ID, Name: "mv", NameCn: "移动文件", Description: "Move file", DescriptionCn: "移动文件"} ) if err := basic.InsertFault(ctx, &fileFaultChmod); err != nil { return err @@ -517,32 +516,32 @@ func InitFileFault(ctx context.Context, fileTarget basic.Target) error { func InitFileTargetArgsChmod(ctx context.Context, fileFault basic.Fault) error { var ( - FileArgsPath = basic.Args{InjectId: fileFault.ID, ExecType: ExecInject, Key: "path", KeyCn: "路径", Description: "target file path", DescriptionCn: "目标文件路径", ValueType: "string", Required: true} - FileArgsPermission = basic.Args{InjectId: fileFault.ID, ExecType: ExecInject, Key: "permission", KeyCn: "权限", Description: "target permissions; 3 integers in [0, 7], according to the Unix permission description specification", DescriptionCn: "目标权限;3个在[0, 7]的整数,按照unix的权限描述规范", ValueType: "string", Required: true} + FileArgsPath = basic.Args{InjectId: fileFault.ID, ExecType: ExecInject, Key: "path", KeyCn: "路径", Description: "Target file path", DescriptionCn: "目标文件路径", ValueType: "string", Required: true} + FileArgsPermission = basic.Args{InjectId: fileFault.ID, ExecType: ExecInject, Key: "permission", KeyCn: "权限", Description: "Target permissions; 3 integers in [0, 7], according to the Unix permission description specification", DescriptionCn: "目标权限,3个在[0, 7]的整数,按照unix的权限描述规范", ValueType: "string", Required: true} ) return basic.InsertArgsMulti(ctx, []*basic.Args{&FileArgsPath, &FileArgsPermission}) } func InitFileTargetArgsDelete(ctx context.Context, fileFault basic.Fault) error { - var FileArgsPath = basic.Args{InjectId: fileFault.ID, ExecType: ExecInject, Key: "path", KeyCn: "路径", Description: "target file path", DescriptionCn: "目标文件路径", ValueType: "string", Required: true} + var FileArgsPath = basic.Args{InjectId: fileFault.ID, ExecType: ExecInject, Key: "path", KeyCn: "路径", Description: "Target file path", DescriptionCn: "目标文件路径", ValueType: "string", Required: true} return basic.InsertArgsMulti(ctx, []*basic.Args{&FileArgsPath}) } func InitFileTargetArgsAppend(ctx context.Context, fileFault basic.Fault) error { var ( - FileArgsPath = basic.Args{InjectId: fileFault.ID, ExecType: ExecInject, Key: "path", KeyCn: "目标文件", Description: "target file path", DescriptionCn: "目标文件路径", ValueType: "string", Required: true} - FileArgsContent = basic.Args{InjectId: fileFault.ID, ExecType: ExecInject, Key: "content", KeyCn: "追加内容", Description: "append content", DescriptionCn: "追加内容", ValueType: "string"} - FileArgsRaw = basic.Args{InjectId: fileFault.ID, ExecType: ExecInject, Key: "raw", KeyCn: "是否追加纯字符串", DefaultValue: "false", Description: "whether to append pure string. By default, it will add some additional identifiers to delete the appended content when recovering; if true, it will append pure string, and the appended content will not be deleted when recovering", DescriptionCn: "是否追加纯字符串。默认false会添加一些额外标识,用于恢复时删掉追加的内容;true追加纯字符串,则恢复时不删掉追加的内容", ValueType: "bool", ValueRule: "true,false"} + FileArgsPath = basic.Args{InjectId: fileFault.ID, ExecType: ExecInject, Key: "path", KeyCn: "目标文件", Description: "Target file path", DescriptionCn: "目标文件路径", ValueType: "string", Required: true} + FileArgsContent = basic.Args{InjectId: fileFault.ID, ExecType: ExecInject, Key: "content", KeyCn: "追加内容", Description: "Append content", DescriptionCn: "追加内容", ValueType: "string"} + FileArgsRaw = basic.Args{InjectId: fileFault.ID, ExecType: ExecInject, Key: "raw", KeyCn: "是否追加纯字符串", DefaultValue: "false", Description: "Whether to append pure string. By default, it will add some additional identifiers to delete the appended content when recovering; if true, it will append pure string, and the appended content will not be deleted when recovering", DescriptionCn: "是否追加纯字符串,默认false会添加一些额外标识,用于恢复时删掉追加的内容;true追加纯字符串,则恢复时不删掉追加的内容", ValueType: "bool", ValueRule: "true,false"} ) return basic.InsertArgsMulti(ctx, []*basic.Args{&FileArgsPath, &FileArgsContent, &FileArgsRaw}) } func InitFileTargetArgsAdd(ctx context.Context, fileFault basic.Fault) error { var ( - FileArgsPath = basic.Args{InjectId: fileFault.ID, ExecType: ExecInject, Key: "path", KeyCn: "目标文件", Description: "target file path", DescriptionCn: "目标文件路径", ValueType: "string", Required: true} - FileArgsContent = basic.Args{InjectId: fileFault.ID, ExecType: ExecInject, Key: "content", KeyCn: "文件内容", Description: "file content", DescriptionCn: "文件内容", ValueType: "string"} - FileArgsPermission = basic.Args{InjectId: fileFault.ID, ExecType: ExecInject, Key: "permission", KeyCn: "创建的文件权限", Unit: "3", UnitCn: "", DefaultValue: "system default permission", Description: "created file permission; integers within [0, 7], according to the unix permission description specification", DescriptionCn: "创建的文件权限; 3个在[0, 7]的整数,按照unix的权限描述规范", ValueType: "string"} - FileArgsForce = basic.Args{InjectId: fileFault.ID, ExecType: ExecInject, Key: "force", KeyCn: "是否覆盖已存在的文件", DefaultValue: "false", Description: "whether to overwrite existing files", DescriptionCn: "是否覆盖已存在的文件", ValueType: "bool", ValueRule: "true,false"} + FileArgsPath = basic.Args{InjectId: fileFault.ID, ExecType: ExecInject, Key: "path", KeyCn: "目标文件", Description: "Target file path", DescriptionCn: "目标文件路径", ValueType: "string", Required: true} + FileArgsContent = basic.Args{InjectId: fileFault.ID, ExecType: ExecInject, Key: "content", KeyCn: "文件内容", Description: "File content", DescriptionCn: "文件内容", ValueType: "string"} + FileArgsPermission = basic.Args{InjectId: fileFault.ID, ExecType: ExecInject, Key: "permission", KeyCn: "创建的文件权限", Unit: "", UnitCn: "", DefaultValue: "", Description: "Created file permission; integers within [0, 7], according to the unix permission description specification", DescriptionCn: "创建的文件权限; 3个在[0, 7]的整数,按照unix的权限描述规范", ValueType: "string"} + FileArgsForce = basic.Args{InjectId: fileFault.ID, ExecType: ExecInject, Key: "force", KeyCn: "是否覆盖已存在的文件", DefaultValue: "false", Description: "Whether to overwrite existing files", DescriptionCn: "是否覆盖已存在的文件", ValueType: "bool", ValueRule: "true,false"} ) return basic.InsertArgsMulti(ctx, []*basic.Args{&FileArgsPath, &FileArgsContent, &FileArgsPermission, &FileArgsForce}) } @@ -557,8 +556,8 @@ func InitFileTargetArgsMove(ctx context.Context, fileFault basic.Fault) error { func InitKernelFault(ctx context.Context, kernelTarget basic.Target) error { var ( - kernelFaultFdfull = basic.Fault{TargetId: kernelTarget.ID, Name: "fdfull", NameCn: "系统fd耗尽", Description: "system fd exhausted, cannot use new fd (open file, create socket, create process), only affects non-root processes", DescriptionCn: "系统fd耗尽,无法使用新fd(打开文件、新建socket、新建进程),只对非root进程有影响; fill模式下,如果系统最大fd数过大,可能会先导致oom"} - kernelFaultNproc = basic.Fault{TargetId: kernelTarget.ID, Name: "nproc", NameCn: "系统nproc满", Description: "target user process count is full, target user cannot create new processes", DescriptionCn: "目标用户进程数打满,目标用户无法创建新进程"} + kernelFaultFdfull = basic.Fault{TargetId: kernelTarget.ID, Name: "fdfull", NameCn: "系统fd耗尽", Description: "System fd exhausted, cannot use new fd (open file, create socket, create process), only affects non-root processes", DescriptionCn: "系统fd耗尽,无法使用新fd(打开文件、新建socket、新建进程),只对非root进程有影响;fill模式下,如果系统最大fd数过大可能会先导致oom"} + kernelFaultNproc = basic.Fault{TargetId: kernelTarget.ID, Name: "nproc", NameCn: "系统nproc满", Description: "Target user process count is full, target user cannot create new processes", DescriptionCn: "目标用户进程数打满,目标用户无法创建新进程"} ) if err := basic.InsertFault(ctx, &kernelFaultFdfull); err != nil { return err @@ -574,94 +573,100 @@ func InitKernelFault(ctx context.Context, kernelTarget basic.Target) error { func InitKernelTargetArgsFdfull(ctx context.Context, KernelFault basic.Fault) error { var ( - KernelArgsCount = basic.Args{InjectId: KernelFault.ID, ExecType: ExecInject, Key: "count", KeyCn: "消耗量", DefaultValue: "0", Description: "fd consumption; integer greater than or equal to 0, 0 means exhausted", DescriptionCn: "fd消耗量; 大于等于0的整数,0表示耗尽", ValueType: "int", ValueRule: ">=0"} - KernelArgsMode = basic.Args{InjectId: KernelFault.ID, ExecType: ExecInject, Key: "mode", KeyCn: "执行模式", DefaultValue: "conf", Description: "execution mode", DescriptionCn: "执行模式", ValueType: "string", ValueRule: "conf,fill"} + KernelArgsCount = basic.Args{InjectId: KernelFault.ID, ExecType: ExecInject, Key: "count", KeyCn: "消耗量", DefaultValue: "0", Description: "fd consumption: an integer greater than or equal to 0, 0 means exhausted", DescriptionCn: "fd消耗量:大于等于0的整数,0表示耗尽", ValueType: "int", ValueRule: ">=0"} + KernelArgsMode = basic.Args{InjectId: KernelFault.ID, ExecType: ExecInject, Key: "mode", KeyCn: "执行模式", DefaultValue: "conf", Description: "Execution mode, conf: by modifying the maximum number of FDs in the system, fill: by real consumption", DescriptionCn: "执行模式,conf:通过修改系统最大fd数,fill:通过真实消耗", ValueType: "string", ValueRule: "conf,fill"} ) return basic.InsertArgsMulti(ctx, []*basic.Args{&KernelArgsCount, &KernelArgsMode}) } func InitKernelTargetArgsNproc(ctx context.Context, KernelFault basic.Fault) error { var ( - KernelArgsCount = basic.Args{InjectId: KernelFault.ID, ExecType: ExecInject, Key: "count", KeyCn: "消耗进程数", DefaultValue: "0", Description: "fd consumption; integer greater than or equal to 0, 0 means exhausted", DescriptionCn: "消耗进程数;大于等于0的整数,0表示耗尽", ValueType: "int", ValueRule: ">=0"} - KernelArgsUser = basic.Args{InjectId: KernelFault.ID, ExecType: ExecInject, Key: "user", KeyCn: "影响用户", Description: "affected user; system user, does not support root user", DescriptionCn: "影响用户; 系统用户,不支持root用户", ValueType: "string"} + KernelArgsCount = basic.Args{InjectId: KernelFault.ID, ExecType: ExecInject, Key: "count", KeyCn: "消耗进程数", DefaultValue: "0", Description: "The number of consumed processes, an integer greater than or equal to 0, 0 means exhausted", DescriptionCn: "消耗进程数,大于等于0的整数,0表示耗尽", ValueType: "int", ValueRule: ">=0"} + KernelArgsUser = basic.Args{InjectId: KernelFault.ID, ExecType: ExecInject, Key: "user", KeyCn: "影响用户", Description: "Affected users, root users are not supported", DescriptionCn: "影响用户,不支持root用户", ValueType: "string"} ) return basic.InsertArgsMulti(ctx, []*basic.Args{&KernelArgsCount, &KernelArgsUser}) } func InitJvmFault(ctx context.Context, jvmTarget basic.Target) error { var ( - jvmFaultMethodDelay = basic.Fault{TargetId: jvmTarget.ID, Name: "methoddelay", NameCn: "Java 运行时方法调用延迟", Description: "inject method call delay into running Java process", DescriptionCn: "对运行中的Java进程注入方法调用延迟"} - jvmFaultMethodReturn = basic.Fault{TargetId: jvmTarget.ID, Name: "methodreturn", NameCn: "Java 运行时方法返回值", Description: "Mock the return value of the specified method in the running Java process", DescriptionCn: "对运行中的Java进程Mock指定方法的返回值"} - javaFaultMethodException = basic.Fault{TargetId: jvmTarget.ID, Name: "methodexception", NameCn: "Java 运行时方法抛出异常", Description: "make the specified method in the running Java process throw an exception when called", DescriptionCn: "使运行中的Java进程的指定方法被调用时抛出异常"} + jvmFaultMethodDelay = basic.Fault{TargetId: jvmTarget.ID, Name: "methoddelay", NameCn: "Java运行时方法调用延迟", Description: "inject method call delay into running Java process", DescriptionCn: "对运行中的Java进程注入方法调用延迟"} + jvmFaultMethodReturn = basic.Fault{TargetId: jvmTarget.ID, Name: "methodreturn", NameCn: "Java运行时篡改返回值", Description: "Mock the return value of the specified method in the running Java process", DescriptionCn: "对运行中的Java进程Mock指定方法的返回值"} + javaFaultMethodException = basic.Fault{TargetId: jvmTarget.ID, Name: "methodexception", NameCn: "Java运行时方法抛出异常", Description: "make the specified method in the running Java process throw an exception when called", DescriptionCn: "使运行中的Java进程的指定方法被调用时抛出异常"} ) if err := basic.InsertFault(ctx, &jvmFaultMethodDelay); err != nil { return err } - if err := InitJvmTargetArgsMethod(ctx, jvmFaultMethodDelay); err != nil { + if err := InitJvmTargetArgsMethod(ctx, jvmFaultMethodDelay, "目标方法以及延迟值", "Comma separated list, element format: class@method@delay milliseconds", "逗号分隔的列表,元素格式:类@方法@延迟毫秒"); err != nil { return err } if err := basic.InsertFault(ctx, &jvmFaultMethodReturn); err != nil { return err } - if err := InitJvmTargetArgsMethod(ctx, jvmFaultMethodReturn); err != nil { + if err := InitJvmTargetArgsMethod(ctx, jvmFaultMethodReturn, "目标方法以及返回值", "Comma separated list, element format: class@method@return value, return integer: Client@say@10, return string: Client@say@\"test\", return variable: Client@say@var", "逗号分隔的列表,元素格式:类@方法@返回值,返回整数:Client@say@10,返回字符串:Client@say@\"test\",返回变量:Client@say@var"); err != nil { return err } if err := basic.InsertFault(ctx, &javaFaultMethodException); err != nil { return err } - return InitJvmTargetArgsMethod(ctx, javaFaultMethodException) + return InitJvmTargetArgsMethod(ctx, javaFaultMethodException, "目标方法以及异常信息", "Comma separated list, element format: class@method@exception description information, example: Client@say@test\"", "逗号分隔的列表,元素格式:类@方法@异常描述信息,样例:Client@say@test") } -func InitJvmTargetArgsMethod(ctx context.Context, javaFault basic.Fault) error { +func InitJvmTargetArgsMethod(ctx context.Context, javaFault basic.Fault, argsMethodKeyCn string, argsMethodDescription string, argsMethodDescriptionCn string) error { var ( - argsKey = basic.Args{InjectId: javaFault.ID, ExecType: ExecInject, Key: "key", KeyCn: "用来筛选受影响进程的关键词", Description: "will use ps -ef | grep [key] to filter", DescriptionCn: "用来筛选受影响进程的关键词;会使用ps -ef | grep [key]来筛选", ValueType: "string"} + argsKey = basic.Args{InjectId: javaFault.ID, ExecType: ExecInject, Key: "key", KeyCn: "进程关键词", Description: "will use ps -ef | grep [key] to filter", DescriptionCn: "用来筛选受影响进程的关键词;会使用ps -ef | grep [key]来筛选", ValueType: "string"} argsPid = basic.Args{InjectId: javaFault.ID, ExecType: ExecInject, Key: "pid", KeyCn: "进程pid", Description: "pid of the running process", DescriptionCn: "存活进程的pid", ValueType: "string"} - argsMethod = basic.Args{InjectId: javaFault.ID, ExecType: ExecInject, Key: "method", KeyCn: "目标方法以及返回值", Description: "target method and delay value, comma-separated list, element format: class@method@delay millisecond", DescriptionCn: "目标方法以及延迟值,逗号分隔的列表,元素格式:类@方法@延迟毫秒", ValueType: "stringlist"} + argsMethod = basic.Args{InjectId: javaFault.ID, ExecType: ExecInject, Key: "method", KeyCn: argsMethodKeyCn, Description: argsMethodDescription, DescriptionCn: argsMethodDescriptionCn, ValueType: "string"} ) return basic.InsertArgsMulti(ctx, []*basic.Args{&argsKey, &argsPid, &argsMethod}) } func InitContainerFault(ctx context.Context, containerTarget basic.Target) error { var ( - containerFaultKill = basic.Fault{TargetId: containerTarget.ID, Name: "kill", NameCn: "杀容器", Description: "kill the target container", DescriptionCn: "把目标容器kill掉"} - containerFaultPause = basic.Fault{TargetId: containerTarget.ID, Name: "pause", NameCn: "暂停容器", Description: "pause the target container", DescriptionCn: "把目标容器暂停运行"} - containerFaultRm = basic.Fault{TargetId: containerTarget.ID, Name: "rm", NameCn: "删除容器", Description: "forcefully remove the target container", DescriptionCn: "强制删除容器"} - containerFaultRestart = basic.Fault{TargetId: containerTarget.ID, Name: "restart", NameCn: "重启容器", Description: "restart the target container", DescriptionCn: "重启容器"} + containerFaultKill = basic.Fault{TargetId: containerTarget.ID, Name: "kill", NameCn: "杀容器", Description: "Kill the target container", DescriptionCn: "把目标容器kill掉"} + containerFaultPause = basic.Fault{TargetId: containerTarget.ID, Name: "pause", NameCn: "暂停容器", Description: "Pause the target container", DescriptionCn: "把目标容器暂停运行"} + containerFaultRm = basic.Fault{TargetId: containerTarget.ID, Name: "rm", NameCn: "删除容器", Description: "Forcefully remove the target container", DescriptionCn: "强制删除容器"} + containerFaultRestart = basic.Fault{TargetId: containerTarget.ID, Name: "restart", NameCn: "重启容器", Description: "Restart the target container", DescriptionCn: "重启容器"} ) if err := basic.InsertFault(ctx, &containerFaultKill); err != nil { return err } - if err := InitContainerArgs(ctx, containerFaultKill); err != nil { + if err := InitContainerArgs(ctx, containerFaultKill, false); err != nil { return err } if err := basic.InsertFault(ctx, &containerFaultPause); err != nil { return err } - if err := InitContainerArgs(ctx, containerFaultPause); err != nil { + if err := InitContainerArgs(ctx, containerFaultPause, false); err != nil { return err } if err := basic.InsertFault(ctx, &containerFaultRm); err != nil { return err } - if err := InitContainerArgs(ctx, containerFaultRm); err != nil { + if err := InitContainerArgs(ctx, containerFaultRm, false); err != nil { return err } if err := basic.InsertFault(ctx, &containerFaultRestart); err != nil { return err } - return InitContainerArgs(ctx, containerFaultRestart) + return InitContainerArgs(ctx, containerFaultRestart, true) } -func InitContainerArgs(ctx context.Context, containerFault basic.Fault) error { +func InitContainerArgs(ctx context.Context, containerFault basic.Fault, isHaveWaitTimeArg bool) error { var ( - ContainerArgsId = basic.Args{InjectId: containerFault.ID, ExecType: ExecInject, Key: "container-id", KeyCn: "目标容器ID", Description: "target container, do not specify the default attack local", DescriptionCn: "目标容器, 不指定默认攻击本地", ValueType: "int"} - ContainerArgsRuntime = basic.Args{InjectId: containerFault.ID, ExecType: ExecInject, Key: "container-runtime", KeyCn: "目标容器runtime", DescriptionCn: "可选docker、pouch,如果指定了container-id,不指定runtime则默认为docker", Description: "docker or pouch, if container-id is specified and runtime is not specified, it defaults to docker", ValueType: "string", ValueRule: "docker,pouch"} + ContainerArgsId = basic.Args{InjectId: containerFault.ID, ExecType: ExecInject, Key: "container-id", KeyCn: "目标容器ID", Description: "Target container, do not specify the default attack local", DescriptionCn: "目标容器,不指定默认攻击本地", ValueType: "int"} + ContainerArgsRuntime = basic.Args{InjectId: containerFault.ID, ExecType: ExecInject, Key: "container-runtime", KeyCn: "目标容器runtime", Description: "Docker or pouch, if container-id is specified and runtime is not specified, it defaults to docker", DescriptionCn: "可选docker、pouch,如果指定了container-id,不指定runtime则默认为docker", ValueType: "string", ValueRule: "docker,pouch"} + ContainerArgsWaitTime = basic.Args{InjectId: containerFault.ID, ExecType: ExecInject, Key: "wait-time(s)", KeyCn: "容器重启可容忍耗时秒数", Description: "The number of seconds a container can tolerate restarting", DescriptionCn: "容器重启可容忍耗时秒数", ValueType: "int", ValueRule: ">0", DefaultValue: "10"} ) - return basic.InsertArgsMulti(ctx, []*basic.Args{&ContainerArgsId, &ContainerArgsRuntime}) + args := []*basic.Args{&ContainerArgsId, &ContainerArgsRuntime} + if isHaveWaitTimeArg { + args = append(args, &ContainerArgsWaitTime) + } + + return basic.InsertArgsMulti(ctx, args) } diff --git a/chaosmeta-platform/pkg/service/inject/inject_k8s.go b/chaosmeta-platform/pkg/service/inject/inject_k8s.go index d848d94..c4172f2 100644 --- a/chaosmeta-platform/pkg/service/inject/inject_k8s.go +++ b/chaosmeta-platform/pkg/service/inject/inject_k8s.go @@ -24,10 +24,10 @@ import ( // k8S-Target func InitK8STarget(ctx context.Context, scope basic.Scope) error { var ( - K8SPodTarget = basic.Target{Name: "pod", NameCn: "pod", Description: "fault injection capabilities related to cloud-native resource pod instances", DescriptionCn: "云原生资源 pod 实例相关的故障注入能力"} - K8SDeploymentTarget = basic.Target{Name: "deployment", NameCn: "deployment", Description: "fault injection capabilities related to cloud-native resource deployment instances", DescriptionCn: "云原生资源 deployment 实例相关的故障注入能力"} - K8SNodeTarget = basic.Target{Name: "node", NameCn: "node", Description: "fault injection capabilities related to cloud-native resource node instances", DescriptionCn: "云原生资源 node 实例相关的故障注入能力"} - K8SClusterTarget = basic.Target{Name: "cluster", NameCn: "cluster", Description: "fault injection capabilities related to kubernetes macro cluster risks", DescriptionCn: "kubernetes 宏观的集群性风险相关的故障注入能力"} + K8SPodTarget = basic.Target{Name: "pod", NameCn: "Pod", Description: "Fault injection capabilities related to cloud-native resource pod instances", DescriptionCn: "云原生资源pod实例相关的故障注入能力"} + K8SDeploymentTarget = basic.Target{Name: "deployment", NameCn: "Deployment", Description: "Fault injection capabilities related to cloud-native resource deployment instances", DescriptionCn: "云原生资源deployment实例相关的故障注入能力"} + K8SNodeTarget = basic.Target{Name: "node", NameCn: "Node", Description: "Fault injection capabilities related to cloud-native resource node instances", DescriptionCn: "云原生资源node实例相关的故障注入能力"} + K8SClusterTarget = basic.Target{Name: "cluster", NameCn: "Cluster", Description: "Fault injection capabilities related to kubernetes macro cluster risks", DescriptionCn: "kubernetes宏观的集群性风险相关的故障注入能力"} ) K8SPodTarget.ScopeId = scope.ID if err := basic.InsertTarget(ctx, &K8SPodTarget); err != nil { @@ -60,12 +60,12 @@ func InitK8STarget(ctx context.Context, scope basic.Scope) error { // pod func InitPodFault(ctx context.Context, podTarget basic.Target) error { var ( - podFaultDelete = basic.Fault{TargetId: podTarget.ID, Name: "delete", NameCn: "删除Pod", Description: "delete the target Pod instance", DescriptionCn: "删除目标Pod实例"} - podFaultLabel = basic.Fault{TargetId: podTarget.ID, Name: "label", NameCn: "修改Pod标签", Description: "modify the label of the target Pod instance", DescriptionCn: "修改目标Pod实例的标签"} - podFaultFinalizer = basic.Fault{TargetId: podTarget.ID, Name: "finalizer", NameCn: "增加Pod finalizer", Description: "add a finalizer to the target Pod instance", DescriptionCn: "为目标Pod实例增加finalizer"} - podFaultContainerKill = basic.Fault{TargetId: podTarget.ID, Name: "containerkill", NameCn: "杀掉Pod中的容器", Description: "kill the specified container in the target Pod instance", DescriptionCn: "杀掉目标Pod实例中指定的容器"} - podFaultContainerPause = basic.Fault{TargetId: podTarget.ID, Name: "containerpause", NameCn: "暂停Pod中的容器", Description: "pauses the specified container in the target Pod instance", DescriptionCn: "暂停目标Pod实例中指定的容器"} - podFaultContainerImage = basic.Fault{TargetId: podTarget.ID, Name: "containerimage", NameCn: "修改Pod容器镜像", Description: "modify the image of the specified container in the target Pod instance", DescriptionCn: "修改目标Pod实例中指定容器的镜像"} + podFaultDelete = basic.Fault{TargetId: podTarget.ID, Name: "delete", NameCn: "删除Pod", Description: "Delete the target Pod instance", DescriptionCn: "删除目标Pod实例"} + podFaultLabel = basic.Fault{TargetId: podTarget.ID, Name: "label", NameCn: "增删Pod标签", Description: "Add or delete the label of the target Pod instance", DescriptionCn: "增删目标Pod实例的标签"} + podFaultFinalizer = basic.Fault{TargetId: podTarget.ID, Name: "finalizer", NameCn: "Pod增加finalizer", Description: "Add a finalizer to the target Pod instance", DescriptionCn: "为目标Pod实例增加finalizer"} + podFaultContainerKill = basic.Fault{TargetId: podTarget.ID, Name: "containerkill", NameCn: "杀掉Pod中的容器", Description: "Kill the specified container in the target Pod instance", DescriptionCn: "杀掉目标Pod实例中指定的容器"} + podFaultContainerPause = basic.Fault{TargetId: podTarget.ID, Name: "containerpause", NameCn: "暂停Pod中的容器", Description: "Pauses the specified container in the target Pod instance", DescriptionCn: "暂停目标Pod实例中指定的容器"} + podFaultContainerImage = basic.Fault{TargetId: podTarget.ID, Name: "containerimage", NameCn: "修改Pod容器镜像", Description: "Modify the image of the specified container in the target Pod instance", DescriptionCn: "修改目标Pod实例中指定容器的镜像"} ) if err := basic.InsertFault(ctx, &podFaultDelete); err != nil { return err @@ -102,35 +102,35 @@ func InitPodFault(ctx context.Context, podTarget basic.Target) error { } func InitPodTargetArgsLabel(ctx context.Context, podFault basic.Fault) error { - argsAdd := basic.Args{InjectId: podFault.ID, ExecType: ExecInject, Key: "add", KeyCn: "增加的标签", ValueType: "string", Description: "added labels;comma-separated key-value pair list", DescriptionCn: "增加的标签; 逗号分隔的键值对列表"} - argsDelete := basic.Args{InjectId: podFault.ID, ExecType: ExecInject, Key: "delete", KeyCn: "删除的标签key", ValueType: "string", Description: "deleted label key; comma-separated key-value pair list", DescriptionCn: "删除的标签"} + argsAdd := basic.Args{InjectId: podFault.ID, ExecType: ExecInject, Key: "add", KeyCn: "增加的标签", ValueType: "string", Description: "Added labels;comma-separated key-value pair list", DescriptionCn: "增加的标签;逗号分隔的键值对列表"} + argsDelete := basic.Args{InjectId: podFault.ID, ExecType: ExecInject, Key: "delete", KeyCn: "删除的标签key", ValueType: "string", Description: "Deleted label key; comma-separated key-value pair list", DescriptionCn: "删除的标签"} return basic.InsertArgsMulti(ctx, []*basic.Args{&argsAdd, &argsDelete}) } func InitPodTargetArgsFinalizer(ctx context.Context, podFault basic.Fault) error { - argsAdd := basic.Args{InjectId: podFault.ID, ExecType: ExecInject, Key: "add", KeyCn: "增加的finalizer", ValueType: "string", Description: "added finalizers; comma-separated key-value pair list", DescriptionCn: "增加的finalizer; 逗号分隔的字符串列表"} - argsDelete := basic.Args{InjectId: podFault.ID, ExecType: ExecInject, Key: "delete", KeyCn: "删除的标签finalizer", ValueType: "string", Description: "deleted finalizer key; comma-separated key-value pair list", DescriptionCn: "删除的finalizer; 逗号分隔的字符串列表"} + argsAdd := basic.Args{InjectId: podFault.ID, ExecType: ExecInject, Key: "add", KeyCn: "增加的finalizer", ValueType: "string", Description: "Added finalizers; comma-separated key-value pair list", DescriptionCn: "增加的finalizer;逗号分隔的字符串列表"} + argsDelete := basic.Args{InjectId: podFault.ID, ExecType: ExecInject, Key: "delete", KeyCn: "删除的标签finalizer", ValueType: "string", Description: "Deleted finalizer key; comma-separated key-value pair list", DescriptionCn: "删除的finalizer;逗号分隔的字符串列表"} return basic.InsertArgsMulti(ctx, []*basic.Args{&argsAdd, &argsDelete}) } func InitPodTargetArgsContainerKillAndPause(ctx context.Context, podFault basic.Fault) error { - argsContainerName := basic.Args{InjectId: podFault.ID, ExecType: ExecInject, Key: "containername", KeyCn: "目标容器名称", ValueType: "string", DefaultValue: "", Description: "target container name; specific container name, or 'firstcontainer' which represents the first container in the pod", DescriptionCn: "目标容器名称; 具体的容器名称,或者“firstcontainer”,表示pod中第一个容器"} + argsContainerName := basic.Args{InjectId: podFault.ID, ExecType: ExecInject, Key: "containername", KeyCn: "目标容器名称", ValueType: "string", DefaultValue: "", Description: "Target container name; specific container name, or 'firstcontainer' which represents the first container in the pod", DescriptionCn: "目标容器名称;具体的容器名称,或者“firstcontainer”,表示pod中第一个容器"} return basic.InsertArgs(ctx, &argsContainerName) } func InitPodTargetArgsContainerImage(ctx context.Context, podFault basic.Fault) error { - argsContainerName := basic.Args{InjectId: podFault.ID, ExecType: ExecInject, Key: "containername", KeyCn: "目标容器名称", ValueType: "string", Description: "target container name; specific container name, or 'firstcontainer' which represents the first container in the pod", DescriptionCn: "目标容器名称; 具体的容器名称, 或者“firstcontainer”,表示pod中第一个容器"} - argsImage := basic.Args{InjectId: podFault.ID, ExecType: ExecInject, Key: "image", KeyCn: "镜像名称", UnitCn: "目标镜像名称", ValueType: "string", DefaultValue: "", Description: "target image name", DescriptionCn: "目标镜像名称"} + argsContainerName := basic.Args{InjectId: podFault.ID, ExecType: ExecInject, Key: "containername", KeyCn: "目标容器名称", ValueType: "string", Description: "Target container name; specific container name, or 'firstcontainer' which represents the first container in the pod", DescriptionCn: "目标容器名称;具体的容器名称,或者“firstcontainer”,表示pod中第一个容器"} + argsImage := basic.Args{InjectId: podFault.ID, ExecType: ExecInject, Key: "image", KeyCn: "镜像名称", UnitCn: "目标镜像名称", ValueType: "string", DefaultValue: "", Description: "Target image name", DescriptionCn: "目标镜像名称"} return basic.InsertArgsMulti(ctx, []*basic.Args{&argsContainerName, &argsImage}) } // deployment func InitDeploymentFault(ctx context.Context, deploymentTarget basic.Target) error { var ( - deploymentFaultDelete = basic.Fault{TargetId: deploymentTarget.ID, Name: "delete", NameCn: "删除deployment", Description: "delete target deployment", DescriptionCn: "删除目标deployment"} - deploymentFaultLabel = basic.Fault{TargetId: deploymentTarget.ID, Name: "label", NameCn: "修改deployment标签", Description: "modify the label of the target deployment", DescriptionCn: "修改目标deployment的标签"} - deploymentFaultFinalizer = basic.Fault{TargetId: deploymentTarget.ID, Name: "finalizer", NameCn: "增加deployment finalizer", Description: "add a finalizer to the target deployment", DescriptionCn: "为目标deployment增加finalizer"} - deploymentFaultReplicas = basic.Fault{TargetId: deploymentTarget.ID, Name: "replicas", NameCn: "篡改deployment副本数", Description: "tampering with the number of copies of the target deployment", DescriptionCn: "篡改目标deployment的副本数"} + deploymentFaultDelete = basic.Fault{TargetId: deploymentTarget.ID, Name: "delete", NameCn: "删除deployment", Description: "Delete target deployment", DescriptionCn: "删除目标deployment"} + deploymentFaultLabel = basic.Fault{TargetId: deploymentTarget.ID, Name: "label", NameCn: "修改deployment标签", Description: "Modify the label of the target deployment", DescriptionCn: "修改目标deployment的标签"} + deploymentFaultFinalizer = basic.Fault{TargetId: deploymentTarget.ID, Name: "finalizer", NameCn: "增加deployment finalizer", Description: "Add a specified finalizer to the deployment instance so that its deletion is blocked or processed by the corresponding recycler.", DescriptionCn: "给deployment实例增加指定的finalizer,使之删除被阻塞或被对应回收器处理"} + deploymentFaultReplicas = basic.Fault{TargetId: deploymentTarget.ID, Name: "replicas", NameCn: "篡改deployment副本数", Description: "Tampering with the number of copies of the target deployment", DescriptionCn: "篡改目标deployment的副本数"} ) if err := basic.InsertFault(ctx, &deploymentFaultDelete); err != nil { return err @@ -161,28 +161,28 @@ func InitDeploymentDeleteArgs(ctx context.Context, deploymentFault basic.Fault) } func InitDeploymentLabelArgs(ctx context.Context, deploymentFault basic.Fault) error { - argsAdd := basic.Args{InjectId: deploymentFault.ID, ExecType: ExecInject, Key: "add", KeyCn: "增加的标签", ValueType: "string", Description: "added labels; a comma-separated list of key-value pairs in the format: k1=v1,k2=v2", DescriptionCn: "增加的标签; 逗号分隔的键值对列表,比如:k1=v1,k2=v2"} - argsDelete := basic.Args{InjectId: deploymentFault.ID, ExecType: ExecInject, Key: "delete", KeyCn: "删除的标签", ValueType: "string", Description: "deleted label; a comma-separated list of strings in the format: k1,k2", DescriptionCn: "删除的标签;逗号分隔的字符串列表,比如:k1,k2"} + argsAdd := basic.Args{InjectId: deploymentFault.ID, ExecType: ExecInject, Key: "add", KeyCn: "增加的标签", ValueType: "string", Description: "Added labels; a comma-separated list of key-value pairs in the format: k1=v1,k2=v2", DescriptionCn: "增加的标签;逗号分隔的键值对列表,比如:k1=v1,k2=v2"} + argsDelete := basic.Args{InjectId: deploymentFault.ID, ExecType: ExecInject, Key: "delete", KeyCn: "删除的标签key", ValueType: "string", Description: "Deleted label; a comma-separated list of strings in the format: k1,k2", DescriptionCn: "删除的标签;逗号分隔的字符串列表,比如:k1,k2"} return basic.InsertArgsMulti(ctx, []*basic.Args{&argsAdd, &argsDelete}) } func InitDeploymentFinalizerArgs(ctx context.Context, deploymentFault basic.Fault) error { - argsAdd := basic.Args{InjectId: deploymentFault.ID, ExecType: ExecInject, Key: "add", KeyCn: "增加finalizer", ValueType: "string", Description: "added finalizer; A comma-separated list of finalizer names in the format: c/1,c/2", DescriptionCn: "增加的finalizer;逗号分隔的finalizer名称列表,格式为:c/1,c/2"} - argsDelete := basic.Args{InjectId: deploymentFault.ID, ExecType: ExecInject, Key: "delete", KeyCn: "删除finalizer", ValueType: "string", DefaultValue: "", Description: "removed finalizers; a comma-separated list of strings in the format: c/1,c/2", DescriptionCn: "删除的finalizer;逗号分隔的finalizer名称列表,格式为:c/1,c/2"} + argsAdd := basic.Args{InjectId: deploymentFault.ID, ExecType: ExecInject, Key: "add", KeyCn: "增加的finalizer", ValueType: "string", Description: "Added finalizer; a comma-separated list of finalizer names in the format: c/1,c/2", DescriptionCn: "增加的finalizer;逗号分隔的finalizer名称列表,格式为:c/1,c/2"} + argsDelete := basic.Args{InjectId: deploymentFault.ID, ExecType: ExecInject, Key: "delete", KeyCn: "删除的finalizer", ValueType: "string", DefaultValue: "", Description: "Removed finalizers; a comma-separated list of strings in the format: c/1,c/2", DescriptionCn: "删除的finalizer;逗号分隔的finalizer名称列表,格式为:c/1,c/2"} return basic.InsertArgsMulti(ctx, []*basic.Args{&argsAdd, &argsDelete}) } func InitDeploymentReplicasArgs(ctx context.Context, deploymentFault basic.Fault) error { - argsMode := basic.Args{InjectId: deploymentFault.ID, ExecType: ExecInject, Key: "mode", KeyCn: "模式", ValueType: "string", DefaultValue: "", Description: "scaling mode", DescriptionCn: "扩缩容模式", ValueRule: "absolutecount,relativecount,relativepercent"} - argsValue := basic.Args{InjectId: deploymentFault.ID, ExecType: ExecInject, Key: "value", KeyCn: "扩所容值", DescriptionCn: "数值,在三种模式下表示不同含义。absolutecount:最终目标副本数;relativecount:相对旧副本数增加或减少了多少个;relativepercent:相对旧副本数增加或减少了百分之多少", Description: "Numerical values, with different meanings in the three modes, absolutecount: the final target number of copies, relativecount: how much has been increased or decreased relative to the number of old copies, relativepercent: the percentage increase or decrease relative to the number of old copies", ValueType: "string", DefaultValue: "", ValueRule: ""} + argsMode := basic.Args{InjectId: deploymentFault.ID, ExecType: ExecInject, Key: "mode", KeyCn: "扩缩模式", ValueType: "string", DefaultValue: "", Description: "Scaling mode", DescriptionCn: "扩缩容模式", ValueRule: "absolutecount,relativecount,relativepercent"} + argsValue := basic.Args{InjectId: deploymentFault.ID, ExecType: ExecInject, Key: "value", KeyCn: "扩缩容大小", Description: "Numerical values, with different meanings in the three modes, absolutecount: the final target number of copies, relativecount: how much has been increased or decreased relative to the number of old copies, relativepercent: the percentage increase or decrease relative to the number of old copies", DescriptionCn: "扩缩容数值,在三种模式下表示不同含义.absolutecount:最终目标副本数;relativecount:相对旧副本数增加或减少了多少个,relativepercent:相对旧副本数增加或减少了百分之多少", ValueType: "string", DefaultValue: "", ValueRule: ""} return basic.InsertArgsMulti(ctx, []*basic.Args{&argsMode, &argsValue}) } // node func InitNodeFault(ctx context.Context, nodeTarget basic.Target) error { var ( - nodeFaultLabel = basic.Fault{TargetId: nodeTarget.ID, Name: "label", NameCn: "修改node标签", Description: "modify the label of the target node", DescriptionCn: "修改目标node的标签"} - nodeFaultTaint = basic.Fault{TargetId: nodeTarget.ID, Name: "taint", NameCn: "增加node taint", Description: "add taint to the target node", DescriptionCn: "为目标node增加taint"} + nodeFaultLabel = basic.Fault{TargetId: nodeTarget.ID, Name: "label", NameCn: "修改node标签", Description: "The label of the node instance is dynamically modified", DescriptionCn: "node实例的label被动态修改"} + nodeFaultTaint = basic.Fault{TargetId: nodeTarget.ID, Name: "taint", NameCn: "为node增加taint", Description: "Add specified stains to node instances to affect pod scheduling logic", DescriptionCn: "给node实例增加指定的污点,影响pod调度逻辑"} ) if err := basic.InsertFault(ctx, &nodeFaultLabel); err != nil { return err @@ -197,14 +197,14 @@ func InitNodeFault(ctx context.Context, nodeTarget basic.Target) error { } func InitNodeLabelArgs(ctx context.Context, nodeFault basic.Fault) error { - argsAdd := basic.Args{InjectId: nodeFault.ID, ExecType: ExecInject, Key: "add", KeyCn: "增加的标签", ValueType: "string", Description: "increased label; a comma-separated list of labels in the format: k1=v1:NoSchedule,k2=v2:NoSchedule", DescriptionCn: "增加的label,逗号分隔的label列表,格式为:k1=v1:NoSchedule,k2=v2:NoSchedule"} - argsDelete := basic.Args{InjectId: nodeFault.ID, ExecType: ExecInject, Key: "delete", KeyCn: "删除的标签", ValueType: "string", Description: "removed label; a comma-separated list of labels in the format: k1=v1:NoSchedule,k2=v2:NoSchedule", DescriptionCn: "删除的label,逗号分隔的label列表,格式为:k1=v1:NoSchedule,k2=v2:NoSchedule"} + argsAdd := basic.Args{InjectId: nodeFault.ID, ExecType: ExecInject, Key: "add", KeyCn: "增加的标签", ValueType: "string", Description: "Increased label;a comma-separated list of labels in the format: k1=v1,k2=v2", DescriptionCn: "增加的label,逗号分隔的label列表,格式为:k1=v1,k2=v2"} + argsDelete := basic.Args{InjectId: nodeFault.ID, ExecType: ExecInject, Key: "delete", KeyCn: "删除的标签", ValueType: "string", Description: "Removed label; a comma-separated list of labels in the format: k1,k2", DescriptionCn: "删除的label,逗号分隔的label列表,格式为:k1,k2"} return basic.InsertArgsMulti(ctx, []*basic.Args{&argsAdd, &argsDelete}) } func InitNodeTaintArgs(ctx context.Context, nodeFault basic.Fault) error { - argsAdd := basic.Args{InjectId: nodeFault.ID, ExecType: ExecInject, Key: "add", KeyCn: "增加的taint", ValueType: "string", DefaultValue: "", Description: "increased taint; a comma-separated list of taints in the format: k1=v1:NoSchedule,k2=v2:NoSchedule", DescriptionCn: "增加的taint; 逗号分隔的taint列表,格式为:k1=v1:NoSchedule,k2=v2:NoSchedule"} - argsDelete := basic.Args{InjectId: nodeFault.ID, ExecType: ExecInject, Key: "delete", KeyCn: "删除的taint", ValueType: "string", DefaultValue: "", Description: "removed taint; a comma-separated list of taints in the format: k1=v1:NoSchedule,k2=v2:NoSchedule", DescriptionCn: "删除的taint;逗号分隔的taint列表,格式为:k1=v1:NoSchedule,k2=v2:NoSchedule"} + argsAdd := basic.Args{InjectId: nodeFault.ID, ExecType: ExecInject, Key: "add", KeyCn: "增加的taint", ValueType: "string", DefaultValue: "", Description: "Increased taint; a comma-separated list of taints in the format: k1=v1:NoSchedule,k2=v2:NoSchedule", DescriptionCn: "增加的taint;逗号分隔的taint列表,格式为:k1=v1:NoSchedule,k2=v2:NoSchedule"} + argsDelete := basic.Args{InjectId: nodeFault.ID, ExecType: ExecInject, Key: "delete", KeyCn: "删除的taint", ValueType: "string", DefaultValue: "", Description: "Removed taint; a comma-separated list of taints in the format: k1=v1:NoSchedule,k2=v2:NoSchedule", DescriptionCn: "删除的taint;逗号分隔的taint列表,格式为:k1=v1:NoSchedule,k2=v2:NoSchedule"} return basic.InsertArgsMulti(ctx, []*basic.Args{&argsAdd, &argsDelete}) } @@ -217,8 +217,8 @@ func InitNodeTaintArgs(ctx context.Context, nodeFault basic.Fault) error { // cluster func InitClusterFault(ctx context.Context, clusterTarget basic.Target) error { var ( - clusterFaultPendingPod = basic.Fault{TargetId: clusterTarget.ID, Name: "pendingpod", NameCn: "堆积pending状态的pod", Description: "accumulate a large number of pods in the pending state for the cluster in batches\"", DescriptionCn: "给集群批量堆积大量pending状态的pod"} - clusterFaultCompletedJob = basic.Fault{TargetId: clusterTarget.ID, Name: "completedjob", NameCn: "堆积completed状态的job", Description: "accumulate a large number of jobs in the completed state in batches for the cluster", DescriptionCn: "给集群批量堆积大量completed状态的job"} + clusterFaultPendingPod = basic.Fault{TargetId: clusterTarget.ID, Name: "pendingpod", NameCn: "堆积pending状态的pod", Description: "Accumulate a large number of pods in the pending state for the cluster in batches", DescriptionCn: "给集群批量堆积大量pending状态的pod"} + clusterFaultCompletedJob = basic.Fault{TargetId: clusterTarget.ID, Name: "completedjob", NameCn: "堆积completed状态的job", Description: "Accumulate a large number of jobs in the completed state in batches for the cluster", DescriptionCn: "给集群批量堆积大量completed状态的job"} ) if err := basic.InsertFault(ctx, &clusterFaultPendingPod); err != nil { return err @@ -237,8 +237,8 @@ func InitClusterPendingPodArgs(ctx context.Context, clusterFault basic.Fault) er } func InitClusterCompletedJobArgs(ctx context.Context, clusterFault basic.Fault) error { - argsCount := basic.Args{InjectId: clusterFault.ID, ExecType: ExecInject, Key: "count", KeyCn: "数量", ValueType: "int", DefaultValue: "", Required: true, Description: "count", DescriptionCn: "数量", ValueRule: ">0"} - argsNamespace := basic.Args{InjectId: clusterFault.ID, ExecType: ExecInject, Key: "namespace", KeyCn: "命名空间", ValueType: "string", DefaultValue: "", Required: true, Description: "namespace", DescriptionCn: "命名空间"} - argsName := basic.Args{InjectId: clusterFault.ID, ExecType: ExecInject, Key: "name", KeyCn: "pod名称前缀", ValueType: "string", DefaultValue: "", Required: true, Description: "pod name prefix", DescriptionCn: "pod名称前缀"} + argsCount := basic.Args{InjectId: clusterFault.ID, ExecType: ExecInject, Key: "count", KeyCn: "数量", ValueType: "int", DefaultValue: "", Required: true, Description: "Count", DescriptionCn: "数量", ValueRule: ">0"} + argsNamespace := basic.Args{InjectId: clusterFault.ID, ExecType: ExecInject, Key: "namespace", KeyCn: "命名空间", ValueType: "string", DefaultValue: "", Required: true, Description: "A namespace that does not exist in the current cluster, such as: \"pendingattack\"", DescriptionCn: "当前集群不存在的namespace,比如:\"pendingattack\""} + argsName := basic.Args{InjectId: clusterFault.ID, ExecType: ExecInject, Key: "name", KeyCn: "pod名称前缀", ValueType: "string", DefaultValue: "", Required: true, Description: "Pod name prefix", DescriptionCn: "pod名称前缀"} return basic.InsertArgsMulti(ctx, []*basic.Args{&argsCount, &argsNamespace, &argsName}) } diff --git a/chaosmeta-platform/pkg/service/kubernetes/kube/node.go b/chaosmeta-platform/pkg/service/kubernetes/kube/node.go index 65679ad..e6bc1e2 100644 --- a/chaosmeta-platform/pkg/service/kubernetes/kube/node.go +++ b/chaosmeta-platform/pkg/service/kubernetes/kube/node.go @@ -576,7 +576,7 @@ func (n *nodeService) TaintOrUnTaint(nodeName, op string, taint *corev1.Taint) ( case "remove": node, err = n.param.KubernetesClient.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{}) if err != nil { - log.Infof("Failed to remove taint: %v", err) + log.Errorf("Failed to remove taint: %v", err) return nil, err } var updated bool diff --git a/chaosmeta-platform/pkg/service/namespace/namespace.go b/chaosmeta-platform/pkg/service/namespace/namespace.go index 279d862..27be34c 100644 --- a/chaosmeta-platform/pkg/service/namespace/namespace.go +++ b/chaosmeta-platform/pkg/service/namespace/namespace.go @@ -71,6 +71,10 @@ func (s *NamespaceService) Create(ctx context.Context, name, description string, Description: description, Creator: creator.ID, } + + if err := namespaceModel.GetNamespaceByName(ctx, namespace); err == nil { + return 0, errors.New("namespace:" + name + " already exists") + } namespaceId, err := namespaceModel.InsertNamespace(ctx, namespace) if err != nil { return 0, err diff --git a/chaosmeta-platform/pkg/service/user/user.go b/chaosmeta-platform/pkg/service/user/user.go index d96fd93..822213f 100644 --- a/chaosmeta-platform/pkg/service/user/user.go +++ b/chaosmeta-platform/pkg/service/user/user.go @@ -110,6 +110,52 @@ func (a *UserService) Login(ctx context.Context, name, password string) (string, return tocken, refreshToken, nil } +//func (a *UserService) LoginWithOauth2(ctx context.Context, code string) (string, string, error) { +// dexConfig := &oauth2.Config{ +// ClientID: "your-client-id", +// ClientSecret: "your-client-secret", +// Scopes: []string{"scope1", "scope2"}, +// RedirectURL: "http://localhost:8080/callback", +// Endpoint: oauth2.Endpoint{ +// AuthURL: "https://authserver.com/auth", +// TokenURL: "https://authserver.com/token", +// }, +// } +// +// token, err := dexConfig.Exchange(context.Background(), code) +// if err != nil { +// return nil, err +// } +// +// userGet := user.User{Email: name} +// if err := user.GetUser(ctx, &userGet); err != nil { +// return "", "", fmt.Errorf("user not registered") +// } +// if userGet.Disabled || userGet.IsDeleted { +// return "", "", errors.ErrUnauthorized() +// } +// if !VerifyPassword(password, userGet.Password) { +// return "", "", errors.ErrUnauthorized() +// } +// +// userGet.LastLoginTime = time.Now() +// if err := user.UpdateUser(ctx, &userGet); err != nil { +// return "", "", err +// } +// +// authentication := Authentication{} +// tocken, err := authentication.GenerateToken(name, string(GrantTypeAccess), 5*time.Minute) +// if err != nil { +// return "", "", err +// } +// +// refreshToken, err := authentication.GenerateToken(name, string(GrantTypeRefresh), time.Hour*24) +// if err != nil { +// return "", "", err +// } +// return tocken, refreshToken, nil +//} + func (a *UserService) Create(ctx context.Context, name, password, role string) (int, error) { hash, err := HashPassword(password) if err != nil { @@ -258,6 +304,13 @@ func (a *UserService) UpdateListRole(ctx context.Context, name string, ids []int if !a.IsAdmin(ctx, name) { return fmt.Errorf("not admin") } + userGet := user.User{Email: name} + user.GetUser(ctx, &userGet) + for _, id := range ids { + if id == userGet.ID { + return fmt.Errorf("admin cannot update own role") + } + } return user.UpdateUsersRole(ctx, ids, role) } diff --git a/chaosmeta-platform/quick-start/platform/configmap.yaml b/chaosmeta-platform/quick-start/platform/configmap.yaml deleted file mode 100644 index efb4139..0000000 --- a/chaosmeta-platform/quick-start/platform/configmap.yaml +++ /dev/null @@ -1,29 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: chaosmeta-platform - namespace: chaosmeta-platform -data: - app.conf: |- - appname = "chaosmeta-platform" - httpaddr = "" - httpport = 8082 - runmode = "dev" - level = INFO - EnableDocs = true - copyrequestbody = true - app.yaml: |- - secretkey: chaosmeta1234567 - argoWorkflowNamespace: default - workflowNamespace: chaosmeta-inject - db: - name: chaosmeta - user: root - passwd: chaosmeta - url: mysql:3306 - maxidle: 30 - maxconn: 30 - log: - path: ./chaosmeta-platform.log - level: info - runmode: ServiceAccount \ No newline at end of file diff --git a/chaosmeta-platform/quick-start/platform/configmap_conf.yaml b/chaosmeta-platform/quick-start/platform/configmap_conf.yaml deleted file mode 100644 index 3c7c299..0000000 --- a/chaosmeta-platform/quick-start/platform/configmap_conf.yaml +++ /dev/null @@ -1,26 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: chaosmeta-platform - namespace: chaosmeta -data: - app.conf: |- - appname = "chaosmeta-platform" - httpaddr = "" - httpport = 8082 - runmode = "dev" - level = INFO - EnableDocs = true - copyrequestbody = true - app.yaml: |- - secretkey: chaosmeta1234567 - db: - name: chaosmeta_platform - user: chaosmeta - passwd: chaosmeta - url: 127.0.0.1:3306 - maxidle: 30 - maxconn: 30 - log: - path: ./chaosmeta-platform.log - level: info \ No newline at end of file diff --git a/chaosmeta-platform/quick-start/platform/deplotment.yaml b/chaosmeta-platform/quick-start/platform/deplotment.yaml deleted file mode 100644 index 81b8fbd..0000000 --- a/chaosmeta-platform/quick-start/platform/deplotment.yaml +++ /dev/null @@ -1,42 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: chaosmeta-platform - namespace: chaosmeta - labels: - release: chaosmeta-platform - app: chaosmeta-platform -spec: - replicas: 1 - selector: - matchLabels: - app: chaosmeta-platform - template: - metadata: - labels: - app: chaosmeta-platform - spec: - serviceAccountName: galaxy - containers: - - name: chaosmeta-platform - imagePullPolicy: Always - image: {{ .Values.depend.image.registry }}:{{ .Values.depend.image.tag }} - resources: - requests: - cpu: "1" - memory: "2Gi" - limits: - cpu: "2" - memory: "4Gi" - volumeMounts: - - name: chaosmeta-config - mountPath: /home/admin/conf - volumes: - - name: chaosmeta-config - configmap: - name: chaosmeta-platform - items: - - key: app.conf - path: app.conf - - key: app.yaml - path: app.yaml diff --git a/chaosmeta-platform/quick-start/platform/deployment.yaml b/chaosmeta-platform/quick-start/platform/deployment.yaml deleted file mode 100644 index c98d86a..0000000 --- a/chaosmeta-platform/quick-start/platform/deployment.yaml +++ /dev/null @@ -1,47 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: chaosmeta-platform - namespace: chaosmeta-platform - labels: - release: chaosmeta-platform - app: chaosmeta-platform -spec: - replicas: 1 - selector: - matchLabels: - app: chaosmeta-platform - template: - metadata: - labels: - app: chaosmeta-platform - spec: - serviceAccountName: chaosmeta-platform - containers: - - name: chaosmeta-platform - imagePullPolicy: Always - image: registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-platform:v0.0.3 - resources: - requests: - cpu: "1" - memory: "2Gi" - limits: - cpu: "2" - memory: "4Gi" - volumeMounts: - - name: chaosmeta-config - mountPath: /home/admin/conf - - name: chaosmeta-platform-frontend - imagePullPolicy: Always - image: registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-platform-frontend:v0.0.1 - ports: - - containerPort: 8000 - volumes: - - name: chaosmeta-config - configMap: - name: chaosmeta-platform - items: - - key: app.conf - path: app.conf - - key: app.yaml - path: app.yaml \ No newline at end of file diff --git a/chaosmeta-platform/quick-start/platform/mysql_deployment.yaml b/chaosmeta-platform/quick-start/platform/mysql_deployment.yaml deleted file mode 100644 index 0787675..0000000 --- a/chaosmeta-platform/quick-start/platform/mysql_deployment.yaml +++ /dev/null @@ -1,73 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: mysql - namespace: chaosmeta-platform -spec: - ports: - - port: 3306 - selector: - app: mysql - clusterIP: None ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: mysql - namespace: chaosmeta-platform -spec: - selector: - matchLabels: - app: mysql - strategy: - type: Recreate - template: - metadata: - labels: - app: mysql - spec: - serviceAccountName: chaosmeta-platform - containers: - - image: mysql:8.0 - name: mysql - env: - - name: MYSQL_DATABASE - value: "chaosmeta" - - name: MYSQL_ROOT_PASSWORD - value: "chaosmeta" - ports: - - containerPort: 3306 - name: mysql - volumeMounts: - - name: mysql-persistent-storage - mountPath: /var/lib/mysql - volumes: - - name: mysql-persistent-storage - persistentVolumeClaim: - claimName: mysql-pv-claim ---- -apiVersion: v1 -kind: PersistentVolume -metadata: - name: mysql-pv-volume - labels: - type: local -spec: - capacity: - storage: 20Gi - accessModes: - - ReadWriteOnce - hostPath: - path: "/mnt/data" ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: mysql-pv-claim - namespace: chaosmeta-platform -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 2Gi \ No newline at end of file diff --git a/chaosmeta-platform/quick-start/platform/rbac.yaml b/chaosmeta-platform/quick-start/platform/rbac.yaml deleted file mode 100644 index afaa226..0000000 --- a/chaosmeta-platform/quick-start/platform/rbac.yaml +++ /dev/null @@ -1,39 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: chaosmeta-platform - namespace: chaosmeta ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: chaosmeta-platform -rules: - - apiGroups: ["*"] - resources: ["*"] - verbs: - - get - - list - - watch - - apiGroups: ["argoproj.io"] - resources: ["*"] - verbs: ["*"] - - apiGroups: ["chaosmeta.io"] - resources: ["*"] - verbs: ["*"] - - apiGroups: ["coordination.k8s.io"] - resources: ["leases"] - verbs: ["*"] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: chaosmeta-platform -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: chaosmeta-platform -subjects: - - kind: ServiceAccount - name: chaosmeta-platform - namespace: default \ No newline at end of file diff --git a/chaosmeta-platform/quick-start/platform/react.yaml b/chaosmeta-platform/quick-start/platform/react.yaml deleted file mode 100644 index e7d37e8..0000000 --- a/chaosmeta-platform/quick-start/platform/react.yaml +++ /dev/null @@ -1,33 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: chaosmeta-platform-app - namespace: chaosmeta-platform -spec: - replicas: 1 - selector: - matchLabels: - app: chaosmeta-platform-app - template: - metadata: - labels: - app: chaosmeta-platform-app - spec: - containers: - - name: chaosmeta-platform-app - image: myusername/chaosmeta-platform-app:latest - ports: - - containerPort: 3000 ---- -apiVersion: v1 -kind: Service -metadata: - name: chaosmeta-platform-app -spec: - selector: - app: chaosmeta-platform-app - ports: - - name: http - port: 80 - targetPort: 3000 - type: LoadBalancer diff --git a/chaosmeta-platform/quick-start/platform/service.yaml b/chaosmeta-platform/quick-start/platform/service.yaml deleted file mode 100644 index b63dabb..0000000 --- a/chaosmeta-platform/quick-start/platform/service.yaml +++ /dev/null @@ -1,33 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - app: chaosmeta-platform-mysql - name: chaosmeta-platform-mysql - namespace: chaosmeta-platform -spec: - ports: - - port: 3306 - protocol: TCP - targetPort: 3306 - selector: - app: chaosmeta-platform-mysql - sessionAffinity: None - type: ClusterIP ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app: chaosmeta-platform - name: chaosmeta-platform - namespace: chaosmeta-platform -spec: - ports: - - name: http - port: 81 - targetPort: 8001 - selector: - app: chaosmeta-platform - sessionAffinity: None - type: LoadBalancer diff --git a/chaosmeta-platform/quick-start/quick-start.yaml b/chaosmeta-platform/quick-start/quick-start.yaml index f88d0b3..ed4785e 100644 --- a/chaosmeta-platform/quick-start/quick-start.yaml +++ b/chaosmeta-platform/quick-start/quick-start.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: ConfigMap metadata: name: chaosmeta-platform - namespace: chaosmeta-platform + namespace: chaosmeta data: app.conf: |- appname = "chaosmeta-platform" @@ -14,13 +14,13 @@ data: copyrequestbody = true app.yaml: |- secretkey: chaosmeta1234567 - argoWorkflowNamespace: default - workflowNamespace: chaosmeta-inject + argoWorkflowNamespace: chaosmeta + workflowNamespace: chaosmeta db: name: chaosmeta user: root passwd: chaosmeta - url: mysql:3306 + url: chaosmeta-mysql:3306 maxidle: 30 maxconn: 30 log: @@ -32,7 +32,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: chaosmeta-platform - namespace: default + namespace: chaosmeta --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole @@ -42,9 +42,9 @@ rules: - apiGroups: ["*"] resources: ["*"] verbs: - - get - - list - - watch + - get + - list + - watch - apiGroups: ["argoproj.io"] resources: ["*"] verbs: ["*"] @@ -66,87 +66,13 @@ roleRef: subjects: - kind: ServiceAccount name: chaosmeta-platform - namespace: default ---- -apiVersion: v1 -kind: Service -metadata: - name: mysql - namespace: chaosmeta-platform -spec: - ports: - - port: 3306 - selector: - app: mysql - clusterIP: None ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: mysql - namespace: chaosmeta-platform -spec: - selector: - matchLabels: - app: mysql - strategy: - type: Recreate - template: - metadata: - labels: - app: mysql - spec: - serviceAccountName: chaosmeta-platform - containers: - - image: mysql:8.0 - name: mysql - env: - - name: MYSQL_DATABASE - value: "chaosmeta" - - name: MYSQL_ROOT_PASSWORD - value: "chaosmeta" - ports: - - containerPort: 3306 - name: mysql - volumeMounts: - - name: mysql-persistent-storage - mountPath: /var/lib/mysql - volumes: - - name: mysql-persistent-storage - persistentVolumeClaim: - claimName: mysql-pv-claim ---- -apiVersion: v1 -kind: PersistentVolume -metadata: - name: mysql-pv-volume - labels: - type: local -spec: - capacity: - storage: 20Gi - accessModes: - - ReadWriteOnce - hostPath: - path: "/mnt/data" ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: mysql-pv-claim - namespace: chaosmeta-platform -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 2Gi + namespace: chaosmeta --- apiVersion: apps/v1 kind: Deployment metadata: name: chaosmeta-platform - namespace: chaosmeta-platform + namespace: chaosmeta labels: release: chaosmeta-platform app: chaosmeta-platform @@ -163,8 +89,7 @@ spec: serviceAccountName: chaosmeta-platform containers: - name: chaosmeta-platform - imagePullPolicy: Always - image: registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-platform:v0.0.3 + image: registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-platform:v0.0.7 resources: requests: cpu: "1" @@ -176,8 +101,7 @@ spec: - name: chaosmeta-config mountPath: /home/admin/conf - name: chaosmeta-platform-frontend - imagePullPolicy: Always - image: registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-platform-frontend:v0.0.1 + image: registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-platform-frontend:v0.0.4 ports: - containerPort: 8000 volumes: @@ -192,11 +116,59 @@ spec: --- apiVersion: v1 kind: Service +metadata: + name: chaosmeta-mysql + namespace: chaosmeta +spec: + ports: + - port: 3306 + selector: + app: chaosmeta-mysql + clusterIP: None +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: chaosmeta-mysql + namespace: chaosmeta +spec: + selector: + matchLabels: + app: chaosmeta-mysql + strategy: + type: Recreate + template: + metadata: + labels: + app: chaosmeta-mysql + spec: + serviceAccountName: chaosmeta-platform + containers: + - image: mysql:8.0 + name: chaosmeta-mysql + env: + - name: MYSQL_DATABASE + value: "chaosmeta" + - name: MYSQL_ROOT_PASSWORD + value: "chaosmeta" + ports: + - containerPort: 3306 + name: chaosmeta-mysql + volumeMounts: + - name: mysql-storage + mountPath: /var/lib/mysql + volumes: + - name: mysql-storage + hostPath: + path: "/mnt/chaosmeta-platform-mysql" +--- +apiVersion: v1 +kind: Service metadata: labels: app: chaosmeta-platform name: chaosmeta-platform - namespace: chaosmeta-platform + namespace: chaosmeta spec: ports: - name: http