From e2d29b8fa2926cc90c1cedde62187ebb79e97d4c Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Wed, 1 Jan 2025 19:13:48 +0800 Subject: [PATCH] feat: configure k8s secret type --- internal/deployer/factory.go | 1 + .../providers/k8s-secret/k8s_secret.go | 14 ++++---- ui/src/components/workflow/End.tsx | 2 +- .../node/DeployNodeFormAliyunCLBFields.tsx | 6 +++- .../DeployNodeFormKubernetesSecretFields.tsx | 28 +++++++++++++-- .../node/DeployNodeFormLocalFields.tsx | 15 +++++--- .../workflow/node/DeployNodeFormSSHFields.tsx | 12 +++++-- .../components/workflow/run/WorkflowRuns.tsx | 2 +- ui/src/domain/workflow.ts | 36 ++++--------------- ui/src/i18n/locales/en/nls.workflow.json | 3 +- .../i18n/locales/en/nls.workflow.nodes.json | 31 ++++++++-------- ui/src/i18n/locales/zh/nls.workflow.json | 3 +- .../i18n/locales/zh/nls.workflow.nodes.json | 18 ++++++---- 13 files changed, 98 insertions(+), 73 deletions(-) diff --git a/internal/deployer/factory.go b/internal/deployer/factory.go index 77fd7d77..fd617d6d 100644 --- a/internal/deployer/factory.go +++ b/internal/deployer/factory.go @@ -221,6 +221,7 @@ func createDeployer(target string, accessConfig string, deployConfig map[string] KubeConfig: access.KubeConfig, Namespace: maps.GetValueOrDefaultAsString(deployConfig, "namespace", "default"), SecretName: maps.GetValueAsString(deployConfig, "secretName"), + SecretType: maps.GetValueOrDefaultAsString(deployConfig, "secretType", "kubernetes.io/tls"), SecretDataKeyForCrt: maps.GetValueOrDefaultAsString(deployConfig, "secretDataKeyForCrt", "tls.crt"), SecretDataKeyForKey: maps.GetValueOrDefaultAsString(deployConfig, "secretDataKeyForKey", "tls.key"), }, logger) diff --git a/internal/pkg/core/deployer/providers/k8s-secret/k8s_secret.go b/internal/pkg/core/deployer/providers/k8s-secret/k8s_secret.go index 8dae9aef..f09e8331 100644 --- a/internal/pkg/core/deployer/providers/k8s-secret/k8s_secret.go +++ b/internal/pkg/core/deployer/providers/k8s-secret/k8s_secret.go @@ -20,13 +20,15 @@ import ( type K8sSecretDeployerConfig struct { // kubeconfig 文件内容。 KubeConfig string `json:"kubeConfig,omitempty"` - // K8s 命名空间。 + // Kubernetes 命名空间。 Namespace string `json:"namespace,omitempty"` - // K8s Secret 名称。 + // Kubernetes Secret 名称。 SecretName string `json:"secretName"` - // K8s Secret 中用于存放证书的 Key。 + // Kubernetes Secret 类型。 + SecretType string `json:"secretType"` + // Kubernetes Secret 中用于存放证书的 Key。 SecretDataKeyForCrt string `json:"secretDataKeyForCrt,omitempty"` - // K8s Secret 中用于存放私钥的 Key。 + // Kubernetes Secret 中用于存放私钥的 Key。 SecretDataKeyForKey string `json:"secretDataKeyForKey,omitempty"` } @@ -102,7 +104,7 @@ func (d *K8sSecretDeployer) Deploy(ctx context.Context, certPem string, privkeyP Name: d.config.SecretName, Annotations: secretAnnotations, }, - Type: k8sCore.SecretType("kubernetes.io/tls"), + Type: k8sCore.SecretType(d.config.SecretType), } secretPayload.Data = make(map[string][]byte) secretPayload.Data[d.config.SecretDataKeyForCrt] = []byte(certPem) @@ -118,7 +120,7 @@ func (d *K8sSecretDeployer) Deploy(ctx context.Context, certPem string, privkeyP } // 更新 Secret 实例 - secretPayload.Type = k8sCore.SecretType("kubernetes.io/tls") + secretPayload.Type = k8sCore.SecretType(d.config.SecretType) if secretPayload.ObjectMeta.Annotations == nil { secretPayload.ObjectMeta.Annotations = secretAnnotations } else { diff --git a/ui/src/components/workflow/End.tsx b/ui/src/components/workflow/End.tsx index 2047a8ea..072674d6 100644 --- a/ui/src/components/workflow/End.tsx +++ b/ui/src/components/workflow/End.tsx @@ -5,7 +5,7 @@ const End = () => { return (
-
{t("workflow_node.end.title")}
+
{t("workflow_node.end.label")}
); }; diff --git a/ui/src/components/workflow/node/DeployNodeFormAliyunCLBFields.tsx b/ui/src/components/workflow/node/DeployNodeFormAliyunCLBFields.tsx index e0ca9b9b..6140bcc2 100644 --- a/ui/src/components/workflow/node/DeployNodeFormAliyunCLBFields.tsx +++ b/ui/src/components/workflow/node/DeployNodeFormAliyunCLBFields.tsx @@ -45,6 +45,10 @@ const DeployNodeFormAliyunCLBFields = () => { const formRule = createSchemaFieldRule(formSchema); const formInst = Form.useFormInstance(); + const initialValues: Partial> = { + listenerPort: 443, + }; + const fieldResourceType = Form.useWatch("resourceType", formInst); return ( @@ -84,7 +88,7 @@ const DeployNodeFormAliyunCLBFields = () => { label={t("workflow_node.deploy.form.aliyun_clb_listener_port.label")} rules={[formRule]} tooltip={} - initialValue={443} + initialValue={initialValues.listenerPort} > diff --git a/ui/src/components/workflow/node/DeployNodeFormKubernetesSecretFields.tsx b/ui/src/components/workflow/node/DeployNodeFormKubernetesSecretFields.tsx index 86594924..f0a234b0 100644 --- a/ui/src/components/workflow/node/DeployNodeFormKubernetesSecretFields.tsx +++ b/ui/src/components/workflow/node/DeployNodeFormKubernetesSecretFields.tsx @@ -17,6 +17,11 @@ const DeployNodeFormKubernetesSecretFields = () => { .nonempty(t("workflow_node.deploy.form.k8s_secret_name.placeholder")) .max(256, t("common.errmsg.string_max", { max: 256 })) .trim(), + secretType: z + .string({ message: t("workflow_node.deploy.form.k8s_secret_type.placeholder") }) + .nonempty(t("workflow_node.deploy.form.k8s_secret_type.placeholder")) + .max(256, t("common.errmsg.string_max", { max: 256 })) + .trim(), secretDataKeyForCrt: z .string({ message: t("workflow_node.deploy.form.k8s_secret_data_key_for_crt.placeholder") }) .nonempty(t("workflow_node.deploy.form.k8s_secret_data_key_for_crt.placeholder")) @@ -30,6 +35,13 @@ const DeployNodeFormKubernetesSecretFields = () => { }); const formRule = createSchemaFieldRule(formSchema); + const initialValues: Partial> = { + namespace: "default", + secretType: "kubernetes.io/tls", + secretDataKeyForCrt: "tls.crt", + secretDataKeyForKey: "tls.key", + }; + return ( <> { label={t("workflow_node.deploy.form.k8s_namespace.label")} rules={[formRule]} tooltip={} - initialValue="default" + initialValue={initialValues.namespace} > @@ -51,12 +63,22 @@ const DeployNodeFormKubernetesSecretFields = () => { + } + initialValue={initialValues.secretType} + > + + + } - initialValue="tls.crt" + initialValue={initialValues.secretDataKeyForCrt} > @@ -66,7 +88,7 @@ const DeployNodeFormKubernetesSecretFields = () => { label={t("workflow_node.deploy.form.k8s_secret_data_key_for_key.label")} rules={[formRule]} tooltip={} - initialValue="tls.key" + initialValue={initialValues.secretDataKeyForKey} > diff --git a/ui/src/components/workflow/node/DeployNodeFormLocalFields.tsx b/ui/src/components/workflow/node/DeployNodeFormLocalFields.tsx index 25024329..7661faa7 100644 --- a/ui/src/components/workflow/node/DeployNodeFormLocalFields.tsx +++ b/ui/src/components/workflow/node/DeployNodeFormLocalFields.tsx @@ -71,6 +71,13 @@ const DeployNodeFormLocalFields = () => { const formRule = createSchemaFieldRule(formSchema); const formInst = Form.useFormInstance(); + const initialValues: Partial> = { + format: FORMAT_PEM, + certPath: "/etc/ssl/certs/cert.crt", + keyPath: "/etc/ssl/certs/cert.key", + shellEnv: SHELLENV_SH, + }; + const fieldFormat = Form.useWatch("format", formInst); const fieldCertPath = Form.useWatch("certPath", formInst); @@ -183,7 +190,7 @@ Remove-Item -Path "$pfxPath" -Force return ( <> - + @@ -213,7 +220,7 @@ Remove-Item -Path "$pfxPath" -Force label={t("workflow_node.deploy.form.local_key_path.label")} rules={[formRule]} tooltip={} - initialValue="/etc/ssl/certs/cert.key" + initialValue={initialValues.keyPath} > @@ -259,7 +266,7 @@ Remove-Item -Path "$pfxPath" -Force - + {t("workflow_node.deploy.form.ssh_format.option.pem.label")} @@ -128,7 +134,7 @@ const DeployNodeFormSSHFields = () => { label={t("workflow_node.deploy.form.ssh_cert_path.label")} rules={[formRule]} tooltip={} - initialValue="/etc/ssl/certs/cert.crt" + initialValue={initialValues.certPath} > @@ -139,7 +145,7 @@ const DeployNodeFormSSHFields = () => { label={t("workflow_node.deploy.form.ssh_key_path.label")} rules={[formRule]} tooltip={} - initialValue="/etc/ssl/certs/cert.key" + initialValue={initialValues.keyPath} > diff --git a/ui/src/components/workflow/run/WorkflowRuns.tsx b/ui/src/components/workflow/run/WorkflowRuns.tsx index b5521bdc..29ebac5e 100644 --- a/ui/src/components/workflow/run/WorkflowRuns.tsx +++ b/ui/src/components/workflow/run/WorkflowRuns.tsx @@ -1,7 +1,7 @@ import { useState } from "react"; import { useTranslation } from "react-i18next"; import { useRequest } from "ahooks"; -import { Button, Empty, notification, Space, Table, theme, Tooltip, Typography, type TableProps } from "antd"; +import { Button, Empty, notification, Space, Table, theme, Typography, type TableProps } from "antd"; import { CheckCircleOutlined as CheckCircleOutlinedIcon, CloseCircleOutlined as CloseCircleOutlinedIcon, diff --git a/ui/src/domain/workflow.ts b/ui/src/domain/workflow.ts index 1ec7156c..82b68ea6 100644 --- a/ui/src/domain/workflow.ts +++ b/ui/src/domain/workflow.ts @@ -4,28 +4,6 @@ import { nanoid } from "nanoid"; import i18n from "@/i18n"; import { deployProvidersMap } from "./provider"; -/** - * @deprecated - */ -export type WorkflowRunLog = { - id: string; - workflow: string; - log: WorkflowRunLogItem[]; - error: string; - succeed: boolean; - created: string; - updated: string; -}; - -/** - * @deprecated - */ -export type WorkflowRunLogItem = { - nodeName: string; - error: string; - outputs: WorkflowOutput[]; -}; - export type WorkflowOutput = { time: string; title: string; @@ -56,13 +34,13 @@ export enum WorkflowNodeType { } export const workflowNodeTypeDefaultName: Map = new Map([ - [WorkflowNodeType.Start, i18n.t("workflow_node.start.title")], - [WorkflowNodeType.End, i18n.t("workflow_node.end.title")], - [WorkflowNodeType.Branch, i18n.t("workflow_node.branch.title")], - [WorkflowNodeType.Condition, i18n.t("workflow_node.condition.title")], - [WorkflowNodeType.Apply, i18n.t("workflow_node.apply.title")], - [WorkflowNodeType.Deploy, i18n.t("workflow_node.deploy.title")], - [WorkflowNodeType.Notify, i18n.t("workflow_node.notify.title")], + [WorkflowNodeType.Start, i18n.t("workflow_node.start.label")], + [WorkflowNodeType.End, i18n.t("workflow_node.end.label")], + [WorkflowNodeType.Branch, i18n.t("workflow_node.branch.label")], + [WorkflowNodeType.Condition, i18n.t("workflow_node.condition.label")], + [WorkflowNodeType.Apply, i18n.t("workflow_node.apply.label")], + [WorkflowNodeType.Deploy, i18n.t("workflow_node.deploy.label")], + [WorkflowNodeType.Notify, i18n.t("workflow_node.notify.label")], [WorkflowNodeType.Custom, i18n.t("workflow_node.custom.title")], ]); diff --git a/ui/src/i18n/locales/en/nls.workflow.json b/ui/src/i18n/locales/en/nls.workflow.json index 7bc59ac9..0a60e7ba 100644 --- a/ui/src/i18n/locales/en/nls.workflow.json +++ b/ui/src/i18n/locales/en/nls.workflow.json @@ -40,6 +40,5 @@ "workflow.common.certificate.label": "Certificate", "workflow.node.setting.label": "Setting Node", "workflow.node.delete.label": "Delete Node", - "workflow.node.addBranch.label": "Add Branch", - "workflow.node.selectNodeType.label": "Select Node Type" + "workflow.node.addBranch.label": "Add Branch" } diff --git a/ui/src/i18n/locales/en/nls.workflow.nodes.json b/ui/src/i18n/locales/en/nls.workflow.nodes.json index 06cd49a7..25ae5a79 100644 --- a/ui/src/i18n/locales/en/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/en/nls.workflow.nodes.json @@ -1,5 +1,5 @@ { - "workflow_node.start.title": "Start", + "workflow_node.start.label": "Start", "workflow_node.start.form.trigger.label": "Trigger", "workflow_node.start.form.trigger.placeholder": "Please select trigger", "workflow_node.start.form.trigger.tooltip": "Auto: Time triggered based on cron expression.
Manual: Manually triggered.", @@ -12,7 +12,7 @@ "workflow_node.start.form.trigger_cron.extra": "Expected execution time for the last 5 times:", "workflow_node.start.form.trigger_cron_alert.content": "Tips: If you have multiple workflows, it is recommended to set them to run at multiple times of the day instead of always running at specific times.

Reference links:
1. Let’s Encrypt rate limits
2. Why should my Let’s Encrypt (ACME) client run at a random time?", - "workflow_node.apply.title": "Application", + "workflow_node.apply.label": "Application", "workflow_node.apply.form.domains.label": "Domains", "workflow_node.apply.form.domains.placeholder": "Please enter domains (separated by semicolons)", "workflow_node.apply.form.domains.tooltip": "Wildcard domain: *.example.com", @@ -40,7 +40,7 @@ "workflow_node.apply.form.disable_follow_cname.label": "Disable CNAME following", "workflow_node.apply.form.disable_follow_cname.tooltip": "It determines whether to disable CNAME following during ACME DNS-01 authentication. If you don't understand this option, just keep it by default.
Learn more.", - "workflow_node.deploy.title": "Deployment", + "workflow_node.deploy.label": "Deployment", "workflow_node.deploy.form.provider_type.label": "Deploy target", "workflow_node.deploy.form.provider_type.placeholder": "Please select deploy target", "workflow_node.deploy.form.provider_access.label": "Host provider authorization", @@ -138,16 +138,19 @@ "workflow_node.deploy.form.huaweicloud_elb_listener_id.placeholder": "Please enter Huawei Cloud ELB listener ID", "workflow_node.deploy.form.huaweicloud_elb_listener_id.tooltip": "For more information, see https://console-intl.huaweicloud.com/vpc/#/elb/list/grid", "workflow_node.deploy.form.k8s_namespace.label": "Kubernetes Namespace", - "workflow_node.deploy.form.k8s_namespace.placeholder": "Please enter Kubernetes namespace", + "workflow_node.deploy.form.k8s_namespace.placeholder": "Please enter Kubernetes Namespace", "workflow_node.deploy.form.k8s_namespace.tooltip": "For more information, see https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/", - "workflow_node.deploy.form.k8s_secret_name.label": "Kubernetes secret name", - "workflow_node.deploy.form.k8s_secret_name.placeholder": "Please enter Kubernetes secret name", + "workflow_node.deploy.form.k8s_secret_name.label": "Kubernetes Secret name", + "workflow_node.deploy.form.k8s_secret_name.placeholder": "Please enter Kubernetes Secret name", "workflow_node.deploy.form.k8s_secret_name.tooltip": "For more information, see https://kubernetes.io/docs/concepts/configuration/secret/", - "workflow_node.deploy.form.k8s_secret_data_key_for_crt.label": "Kubernetes secret data key for certificate", - "workflow_node.deploy.form.k8s_secret_data_key_for_crt.placeholder": "Please enter secret data key for certificate", + "workflow_node.deploy.form.k8s_secret_type.label": "Kubernetes Secret type", + "workflow_node.deploy.form.k8s_secret_type.placeholder": "Please enter Kubernetes Secret type", + "workflow_node.deploy.form.k8s_secret_type.tooltip": "For more information, see https://kubernetes.io/docs/concepts/configuration/secret/", + "workflow_node.deploy.form.k8s_secret_data_key_for_crt.label": "Kubernetes Secret data key for certificate", + "workflow_node.deploy.form.k8s_secret_data_key_for_crt.placeholder": "Please enter Kubernetes Secret data key for certificate", "workflow_node.deploy.form.k8s_secret_data_key_for_crt.tooltip": "For more information, see https://kubernetes.io/docs/concepts/configuration/secret/", - "workflow_node.deploy.form.k8s_secret_data_key_for_key.label": "Kubernetes secret data key for private key", - "workflow_node.deploy.form.k8s_secret_data_key_for_key.placeholder": "Please enter secret data key for private key", + "workflow_node.deploy.form.k8s_secret_data_key_for_key.label": "Kubernetes Secret data key for private key", + "workflow_node.deploy.form.k8s_secret_data_key_for_key.placeholder": "Please enter Kubernetes Secret data key for private key", "workflow_node.deploy.form.k8s_secret_data_key_for_key.tooltip": "For more information, see https://kubernetes.io/docs/concepts/configuration/secret/", "workflow_node.deploy.form.local_format.label": "File format", "workflow_node.deploy.form.local_format.placeholder": "Please select file format", @@ -270,7 +273,7 @@ "workflow_node.deploy.form.webhook_data.label": "Webhook data (JSON format)", "workflow_node.deploy.form.webhook_data.placeholder": "Please enter Webhook data", - "workflow_node.notify.title": "Notification", + "workflow_node.notify.label": "Notification", "workflow_node.notify.form.subject.label": "Subject", "workflow_node.notify.form.subject.placeholder": "Please enter subject", "workflow_node.notify.form.message.label": "Message", @@ -279,9 +282,9 @@ "workflow_node.notify.form.channel.placeholder": "Please select channel", "workflow_node.notify.form.channel.button": "Configure", - "workflow_node.end.title": "End", + "workflow_node.end.label": "End", - "workflow_node.branch.title": "Branch", + "workflow_node.branch.label": "Branch", - "workflow_node.condition.title": "Condition" + "workflow_node.condition.label": "Condition" } diff --git a/ui/src/i18n/locales/zh/nls.workflow.json b/ui/src/i18n/locales/zh/nls.workflow.json index c0889161..78ed5373 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.json +++ b/ui/src/i18n/locales/zh/nls.workflow.json @@ -40,6 +40,5 @@ "workflow.common.certificate.label": "证书", "workflow.node.setting.label": "设置节点", "workflow.node.delete.label": "删除节点", - "workflow.node.addBranch.label": "添加分支", - "workflow.node.selectNodeType.label": "选择节点类型" + "workflow.node.addBranch.label": "添加分支" } diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json index 136d8bb9..bdb419a2 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json @@ -1,5 +1,5 @@ { - "workflow_node.start.title": "开始", + "workflow_node.start.label": "开始", "workflow_node.start.form.trigger.label": "触发方式", "workflow_node.start.form.trigger.placeholder": "请选择触发方式", "workflow_node.start.form.trigger.tooltip": "自动触发:基于 Cron 表达式定时触发。
手动触发:手动点击执行触发。", @@ -12,7 +12,7 @@ "workflow_node.start.form.trigger_cron.extra": "预计最近 5 次执行时间:", "workflow_node.start.form.trigger_cron_alert.content": "小贴士:如果你有多个工作流,建议将它们设置为在一天中的多个时间段运行,而非总是在相同的特定时间。

参考链接:
1. Let’s Encrypt 速率限制
2. 为什么我的 Let’s Encrypt (ACME) 客户端启动时间应当随机?", - "workflow_node.apply.title": "申请", + "workflow_node.apply.label": "申请", "workflow_node.apply.form.domains.label": "域名", "workflow_node.apply.form.domains.placeholder": "请输入域名(多个值请用半角分号隔开)", "workflow_node.apply.form.domains.tooltip": "泛域名表示形式为:*.example.com", @@ -40,7 +40,7 @@ "workflow_node.apply.form.disable_follow_cname.label": "禁止 CNAME 跟随", "workflow_node.apply.form.disable_follow_cname.tooltip": "在 ACME DNS-01 认证时是否禁止 CNAME 跟随。如果你不了解该选项的用途,保持默认即可。
点此了解更多。", - "workflow_node.deploy.title": "部署", + "workflow_node.deploy.label": "部署", "workflow_node.deploy.form.provider_type.label": "部署目标", "workflow_node.deploy.form.provider_type.placeholder": "请选择部署目标", "workflow_node.deploy.form.provider_access.label": "主机提供商授权", @@ -143,6 +143,9 @@ "workflow_node.deploy.form.k8s_secret_name.label": "Kubernetes Secret 名称", "workflow_node.deploy.form.k8s_secret_name.placeholder": "请输入 Kubernetes Secret 名称", "workflow_node.deploy.form.k8s_secret_name.tooltip": "这是什么?请参阅 https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/", + "workflow_node.deploy.form.k8s_secret_type.label": "Kubernetes Secret 类型", + "workflow_node.deploy.form.k8s_secret_type.placeholder": "请输入 Kubernetes Secret 类型", + "workflow_node.deploy.form.k8s_secret_type.tooltip": "这是什么?请参阅 https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/", "workflow_node.deploy.form.k8s_secret_data_key_for_crt.label": "Kubernetes Secret 数据键(用于存放证书的字段)", "workflow_node.deploy.form.k8s_secret_data_key_for_crt.placeholder": "请输入 Kubernetes Secret 中用于存放证书的数据键", "workflow_node.deploy.form.k8s_secret_data_key_for_crt.tooltip": "这是什么?请参阅 https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/", @@ -270,7 +273,7 @@ "workflow_node.deploy.form.webhook_data.label": "Webhook 回调数据(JSON 格式)", "workflow_node.deploy.form.webhook_data.placeholder": "请输入 Webhook 回调数据", - "workflow_node.notify.title": "通知", + "workflow_node.notify.label": "通知", "workflow_node.notify.form.subject.label": "通知主题", "workflow_node.notify.form.subject.placeholder": "请输入通知主题", "workflow_node.notify.form.message.label": "通知内容", @@ -279,8 +282,9 @@ "workflow_node.notify.form.channel.placeholder": "请选择通知渠道", "workflow_node.notify.form.channel.button": "去配置", - "workflow_node.end.title": "结束", + "workflow_node.end.label": "结束", - "workflow_node.branch.title": "分支", - "workflow_node.condition.title": "条件" + "workflow_node.branch.label": "分支", + + "workflow_node.condition.label": "条件" }