From 980d1ee0b9a327e6f53aea35c2e4b67405568889 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Fri, 16 May 2025 20:15:59 +0800 Subject: [PATCH] feat: new deployment providers: ratpanel console & site --- internal/domain/access.go | 2 +- .../ratpanel-console/ratpanel_console.go | 11 +-- .../ratpanel-console/ratpanel_console_test.go | 20 ++--- .../providers/ratpanel-site/ratpanel_site.go | 13 +-- .../ratpanel-site/ratpanel_site_test.go | 20 ++--- internal/pkg/sdk3rd/ratpanel/client.go | 8 +- ui/public/imgs/providers/ratpanel.png | Bin 0 -> 7269 bytes ui/src/components/access/AccessForm.tsx | 3 + .../access/AccessFormRatPanelConfig.tsx | 82 ++++++++++++++++++ .../provider/DeploymentProviderPicker.tsx | 2 + .../workflow/node/DeployNodeConfigForm.tsx | 3 + ...DeployNodeConfigFormRatPanelSiteConfig.tsx | 63 ++++++++++++++ .../DeployNodeConfigFormSafeLineConfig.tsx | 7 +- ui/src/domain/access.ts | 8 ++ ui/src/domain/provider.ts | 28 +++--- ui/src/i18n/locales/en/nls.access.json | 11 +++ ui/src/i18n/locales/en/nls.provider.json | 5 ++ .../i18n/locales/en/nls.workflow.nodes.json | 6 +- ui/src/i18n/locales/zh/nls.access.json | 11 +++ ui/src/i18n/locales/zh/nls.provider.json | 5 ++ .../i18n/locales/zh/nls.workflow.nodes.json | 10 ++- 21 files changed, 267 insertions(+), 51 deletions(-) create mode 100644 ui/public/imgs/providers/ratpanel.png create mode 100644 ui/src/components/access/AccessFormRatPanelConfig.tsx create mode 100644 ui/src/components/workflow/node/DeployNodeConfigFormRatPanelSiteConfig.tsx diff --git a/internal/domain/access.go b/internal/domain/access.go index 82f20bbd..9ab18b9f 100644 --- a/internal/domain/access.go +++ b/internal/domain/access.go @@ -243,7 +243,7 @@ type AccessConfigForRainYun struct { type AccessConfigForRatPanel struct { ApiUrl string `json:"apiUrl"` - AccessTokenId uint `json:"accessTokenId"` + AccessTokenId int32 `json:"accessTokenId"` AccessToken string `json:"accessToken"` AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"` } diff --git a/internal/pkg/core/deployer/providers/ratpanel-console/ratpanel_console.go b/internal/pkg/core/deployer/providers/ratpanel-console/ratpanel_console.go index ceb31771..51faf4f2 100644 --- a/internal/pkg/core/deployer/providers/ratpanel-console/ratpanel_console.go +++ b/internal/pkg/core/deployer/providers/ratpanel-console/ratpanel_console.go @@ -15,8 +15,8 @@ import ( type DeployerConfig struct { // 耗子面板地址。 ApiUrl string `json:"apiUrl"` - // 耗子面板访问令牌ID。 - AccessTokenId uint `json:"accessTokenId"` + // 耗子面板访问令牌 ID。 + AccessTokenId int32 `json:"accessTokenId"` // 耗子面板访问令牌。 AccessToken string `json:"accessToken"` // 是否允许不安全的连接。 @@ -64,15 +64,15 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE PrivateKey: privkeyPEM, } settingCertResp, err := d.sdkClient.SettingCert(settingCertReq) - d.logger.Debug("sdk request 'ratpanel.SettingCertRequest'", slog.Any("request", settingCertReq), slog.Any("response", settingCertResp)) + d.logger.Debug("sdk request 'ratpanel.SettingCert'", slog.Any("request", settingCertReq), slog.Any("response", settingCertResp)) if err != nil { - return nil, fmt.Errorf("failed to execute sdk request 'ratpanel.SettingCertRequest': %w", err) + return nil, fmt.Errorf("failed to execute sdk request 'ratpanel.SettingCert': %w", err) } return &deployer.DeployResult{}, nil } -func createSdkClient(apiUrl string, accessTokenId uint, accessToken string, skipTlsVerify bool) (*rpsdk.Client, error) { +func createSdkClient(apiUrl string, accessTokenId int32, accessToken string, skipTlsVerify bool) (*rpsdk.Client, error) { if _, err := url.Parse(apiUrl); err != nil { return nil, errors.New("invalid ratpanel api url") } @@ -80,6 +80,7 @@ func createSdkClient(apiUrl string, accessTokenId uint, accessToken string, skip if accessTokenId == 0 { return nil, errors.New("invalid ratpanel access token id") } + if accessToken == "" { return nil, errors.New("invalid ratpanel access token") } diff --git a/internal/pkg/core/deployer/providers/ratpanel-console/ratpanel_console_test.go b/internal/pkg/core/deployer/providers/ratpanel-console/ratpanel_console_test.go index 40804f87..3f3193b3 100644 --- a/internal/pkg/core/deployer/providers/ratpanel-console/ratpanel_console_test.go +++ b/internal/pkg/core/deployer/providers/ratpanel-console/ratpanel_console_test.go @@ -15,8 +15,8 @@ var ( fInputCertPath string fInputKeyPath string fApiUrl string - fTokenId uint - fToken string + fAccessTokenId int64 + fAccessToken string ) func init() { @@ -25,8 +25,8 @@ func init() { flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "") flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "") flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "") - flag.UintVar(&fTokenId, argsPrefix+"TOKENID", 0, "") - flag.StringVar(&fToken, argsPrefix+"TOKEN", "", "") + flag.Int64Var(&fAccessTokenId, argsPrefix+"ACCESSTOKENID", 0, "") + flag.StringVar(&fAccessToken, argsPrefix+"ACCESSTOKEN", "", "") } /* @@ -36,8 +36,8 @@ Shell command to run this test: --CERTIMATE_DEPLOYER_RATPANELCONSOLE_INPUTCERTPATH="/path/to/your-input-cert.pem" \ --CERTIMATE_DEPLOYER_RATPANELCONSOLE_INPUTKEYPATH="/path/to/your-input-key.pem" \ --CERTIMATE_DEPLOYER_RATPANELCONSOLE_APIURL="http://127.0.0.1:8888" \ - --CERTIMATE_DEPLOYER_RATPANELCONSOLE_TOKENID=your-access-token-id \ - --CERTIMATE_DEPLOYER_RATPANELCONSOLE_TOKEN="your-access-token" + --CERTIMATE_DEPLOYER_RATPANELCONSOLE_ACCESSTOKENID="your-access-token-id" \ + --CERTIMATE_DEPLOYER_RATPANELCONSOLE_ACCESSTOKEN="your-access-token" */ func TestDeploy(t *testing.T) { flag.Parse() @@ -48,14 +48,14 @@ func TestDeploy(t *testing.T) { fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath), fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath), fmt.Sprintf("APIURL: %v", fApiUrl), - fmt.Sprintf("TOKENID: %v", fTokenId), - fmt.Sprintf("TOKEN: %v", fToken), + fmt.Sprintf("ACCESSTOKENID: %v", fAccessTokenId), + fmt.Sprintf("ACCESSTOKEN: %v", fAccessToken), }, "\n")) deployer, err := provider.NewDeployer(&provider.DeployerConfig{ ApiUrl: fApiUrl, - AccessTokenId: fTokenId, - AccessToken: fToken, + AccessTokenId: int32(fAccessTokenId), + AccessToken: fAccessToken, AllowInsecureConnections: true, }) if err != nil { diff --git a/internal/pkg/core/deployer/providers/ratpanel-site/ratpanel_site.go b/internal/pkg/core/deployer/providers/ratpanel-site/ratpanel_site.go index 85f54ab5..b4e283be 100644 --- a/internal/pkg/core/deployer/providers/ratpanel-site/ratpanel_site.go +++ b/internal/pkg/core/deployer/providers/ratpanel-site/ratpanel_site.go @@ -15,14 +15,14 @@ import ( type DeployerConfig struct { // 耗子面板地址。 ApiUrl string `json:"apiUrl"` - // 耗子面板访问令牌ID。 - AccessTokenId uint `json:"accessTokenId"` + // 耗子面板访问令牌 ID。 + AccessTokenId int32 `json:"accessTokenId"` // 耗子面板访问令牌。 AccessToken string `json:"accessToken"` // 是否允许不安全的连接。 AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"` // 网站名称。 - SiteName string `json:"siteName,omitempty"` + SiteName string `json:"siteName"` } type DeployerProvider struct { @@ -71,15 +71,15 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE PrivateKey: privkeyPEM, } websiteCertResp, err := d.sdkClient.WebsiteCert(websiteCertReq) - d.logger.Debug("sdk request 'ratpanel.WebsiteCertRequest'", slog.Any("request", websiteCertReq), slog.Any("response", websiteCertResp)) + d.logger.Debug("sdk request 'ratpanel.WebsiteCert'", slog.Any("request", websiteCertReq), slog.Any("response", websiteCertResp)) if err != nil { - return nil, fmt.Errorf("failed to execute sdk request 'ratpanel.WebsiteCertRequest': %w", err) + return nil, fmt.Errorf("failed to execute sdk request 'ratpanel.WebsiteCert': %w", err) } return &deployer.DeployResult{}, nil } -func createSdkClient(apiUrl string, accessTokenId uint, accessToken string, skipTlsVerify bool) (*rpsdk.Client, error) { +func createSdkClient(apiUrl string, accessTokenId int32, accessToken string, skipTlsVerify bool) (*rpsdk.Client, error) { if _, err := url.Parse(apiUrl); err != nil { return nil, errors.New("invalid ratpanel api url") } @@ -87,6 +87,7 @@ func createSdkClient(apiUrl string, accessTokenId uint, accessToken string, skip if accessTokenId == 0 { return nil, errors.New("invalid ratpanel access token id") } + if accessToken == "" { return nil, errors.New("invalid ratpanel access token") } diff --git a/internal/pkg/core/deployer/providers/ratpanel-site/ratpanel_site_test.go b/internal/pkg/core/deployer/providers/ratpanel-site/ratpanel_site_test.go index a4cab040..658175fb 100644 --- a/internal/pkg/core/deployer/providers/ratpanel-site/ratpanel_site_test.go +++ b/internal/pkg/core/deployer/providers/ratpanel-site/ratpanel_site_test.go @@ -15,8 +15,8 @@ var ( fInputCertPath string fInputKeyPath string fApiUrl string - fTokenId uint - fToken string + fAccessTokenId int64 + fAccessToken string fSiteName string ) @@ -26,8 +26,8 @@ func init() { flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "") flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "") flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "") - flag.UintVar(&fTokenId, argsPrefix+"TOKENID", 0, "") - flag.StringVar(&fToken, argsPrefix+"TOKEN", "", "") + flag.Int64Var(&fAccessTokenId, argsPrefix+"ACCESSTOKENID", 0, "") + flag.StringVar(&fAccessToken, argsPrefix+"ACCESSTOKEN", "", "") flag.StringVar(&fSiteName, argsPrefix+"SITENAME", "", "") } @@ -38,8 +38,8 @@ Shell command to run this test: --CERTIMATE_DEPLOYER_RATPANELSITE_INPUTCERTPATH="/path/to/your-input-cert.pem" \ --CERTIMATE_DEPLOYER_RATPANELSITE_INPUTKEYPATH="/path/to/your-input-key.pem" \ --CERTIMATE_DEPLOYER_RATPANELSITE_APIURL="http://127.0.0.1:8888" \ - --CERTIMATE_DEPLOYER_RATPANELSITE_TOKENID=your-access-token-id \ - --CERTIMATE_DEPLOYER_RATPANELSITE_TOKEN="your-access-token" \ + --CERTIMATE_DEPLOYER_RATPANELSITE_ACCESSTOKENID="your-access-token-id" \ + --CERTIMATE_DEPLOYER_RATPANELSITE_ACCESSTOKEN="your-access-token" \ --CERTIMATE_DEPLOYER_RATPANELSITE_SITENAME="your-site-name" */ func TestDeploy(t *testing.T) { @@ -51,15 +51,15 @@ func TestDeploy(t *testing.T) { fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath), fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath), fmt.Sprintf("APIURL: %v", fApiUrl), - fmt.Sprintf("TOKENID: %v", fTokenId), - fmt.Sprintf("TOKEN: %v", fToken), + fmt.Sprintf("ACCESSTOKENID: %v", fAccessTokenId), + fmt.Sprintf("ACCESSTOKEN: %v", fAccessToken), fmt.Sprintf("SITENAME: %v", fSiteName), }, "\n")) deployer, err := provider.NewDeployer(&provider.DeployerConfig{ ApiUrl: fApiUrl, - AccessTokenId: fTokenId, - AccessToken: fToken, + AccessTokenId: int32(fAccessTokenId), + AccessToken: fAccessToken, AllowInsecureConnections: true, SiteName: fSiteName, }) diff --git a/internal/pkg/sdk3rd/ratpanel/client.go b/internal/pkg/sdk3rd/ratpanel/client.go index e0562410..ac2c4062 100644 --- a/internal/pkg/sdk3rd/ratpanel/client.go +++ b/internal/pkg/sdk3rd/ratpanel/client.go @@ -20,7 +20,7 @@ type Client struct { client *resty.Client } -func NewClient(apiHost string, accessTokenId uint, accessToken string) *Client { +func NewClient(apiHost string, accessTokenId int32, accessToken string) *Client { client := resty.New(). SetBaseURL(strings.TrimRight(apiHost, "/")+"/api"). SetHeader("Accept", "application/json"). @@ -123,9 +123,9 @@ func (c *Client) sendRequestWithResult(method string, path string, params interf } if err = json.Unmarshal(resp.Body(), &result); err != nil { - return fmt.Errorf("ratpanel api error: failed to parse response: %w", err) - } else if errmessage := result.GetMessage(); errmessage != "success" { - return fmt.Errorf("ratpanel api error: %d - %s", resp.StatusCode(), errmessage) + return fmt.Errorf("ratpanel api error: failed to unmarshal response: %w", err) + } else if errmsg := result.GetMessage(); errmsg != "success" { + return fmt.Errorf("ratpanel api error: message='%s'", errmsg) } return nil diff --git a/ui/public/imgs/providers/ratpanel.png b/ui/public/imgs/providers/ratpanel.png new file mode 100644 index 0000000000000000000000000000000000000000..f89808dd4ba41c08ef7eece485b1d1bcb26dac45 GIT binary patch literal 7269 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 A`Tzg` literal 0 HcmV?d00001 diff --git a/ui/src/components/access/AccessForm.tsx b/ui/src/components/access/AccessForm.tsx index 1b618cbc..3e31dad4 100644 --- a/ui/src/components/access/AccessForm.tsx +++ b/ui/src/components/access/AccessForm.tsx @@ -54,6 +54,7 @@ import AccessFormPowerDNSConfig from "./AccessFormPowerDNSConfig"; import AccessFormProxmoxVEConfig from "./AccessFormProxmoxVEConfig"; import AccessFormQiniuConfig from "./AccessFormQiniuConfig"; import AccessFormRainYunConfig from "./AccessFormRainYunConfig"; +import AccessFormRatPanelConfig from "./AccessFormRatPanelConfig"; import AccessFormSafeLineConfig from "./AccessFormSafeLineConfig"; import AccessFormSSHConfig from "./AccessFormSSHConfig"; import AccessFormSSLComConfig from "./AccessFormSSLComConfig"; @@ -260,6 +261,8 @@ const AccessForm = forwardRef(({ className, return ; case ACCESS_PROVIDERS.RAINYUN: return ; + case ACCESS_PROVIDERS.RATPANEL: + return ; case ACCESS_PROVIDERS.SAFELINE: return ; case ACCESS_PROVIDERS.SSH: diff --git a/ui/src/components/access/AccessFormRatPanelConfig.tsx b/ui/src/components/access/AccessFormRatPanelConfig.tsx new file mode 100644 index 00000000..ca3d2182 --- /dev/null +++ b/ui/src/components/access/AccessFormRatPanelConfig.tsx @@ -0,0 +1,82 @@ +import { useTranslation } from "react-i18next"; +import { Form, type FormInstance, Input, Switch } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { type AccessConfigForRatPanel } from "@/domain/access"; + +type AccessFormRatPanelConfigFieldValues = Nullish; + +export type AccessFormRatPanelConfigProps = { + form: FormInstance; + formName: string; + disabled?: boolean; + initialValues?: AccessFormRatPanelConfigFieldValues; + onValuesChange?: (values: AccessFormRatPanelConfigFieldValues) => void; +}; + +const initFormModel = (): AccessFormRatPanelConfigFieldValues => { + return { + apiUrl: "http://:8888/", + accessTokenId: 1, + accessToken: "", + }; +}; + +const AccessFormRatPanelConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormRatPanelConfigProps) => { + const { t } = useTranslation(); + + const formSchema = z.object({ + apiUrl: z.string().url(t("common.errmsg.url_invalid")), + accessTokenId: z.preprocess((v) => Number(v), z.number().positive(t("access.form.ratpanel_access_token_id.placeholder"))), + accessToken: z.string().nonempty(t("access.form.ratpanel_access_token.placeholder")).trim(), + allowInsecureConnections: z.boolean().nullish(), + }); + const formRule = createSchemaFieldRule(formSchema); + + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); + }; + + return ( +
+ + + + + } + > + + + + } + > + + + + + + +
+ ); +}; + +export default AccessFormRatPanelConfig; diff --git a/ui/src/components/provider/DeploymentProviderPicker.tsx b/ui/src/components/provider/DeploymentProviderPicker.tsx index 0ea5a97c..b1bcd6fe 100644 --- a/ui/src/components/provider/DeploymentProviderPicker.tsx +++ b/ui/src/components/provider/DeploymentProviderPicker.tsx @@ -72,8 +72,10 @@ const DeploymentProviderPicker = ({ className, style, autoFocus, filter, placeho DEPLOYMENT_CATEGORIES.LOADBALANCE, DEPLOYMENT_CATEGORIES.FIREWALL, DEPLOYMENT_CATEGORIES.AV, + DEPLOYMENT_CATEGORIES.APIGATEWAY, DEPLOYMENT_CATEGORIES.SERVERLESS, DEPLOYMENT_CATEGORIES.WEBSITE, + DEPLOYMENT_CATEGORIES.SSL, DEPLOYMENT_CATEGORIES.NAS, DEPLOYMENT_CATEGORIES.OTHER, ].map((key) => ({ diff --git a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx index 9e4ade18..b77ff9cf 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx @@ -63,6 +63,7 @@ import DeployNodeConfigFormQiniuCDNConfig from "./DeployNodeConfigFormQiniuCDNCo import DeployNodeConfigFormQiniuKodoConfig from "./DeployNodeConfigFormQiniuKodoConfig"; import DeployNodeConfigFormQiniuPiliConfig from "./DeployNodeConfigFormQiniuPiliConfig"; import DeployNodeConfigFormRainYunRCDNConfig from "./DeployNodeConfigFormRainYunRCDNConfig"; +import DeployNodeConfigFormRatPanelSiteConfig from "./DeployNodeConfigFormRatPanelSiteConfig"; import DeployNodeConfigFormSafeLineConfig from "./DeployNodeConfigFormSafeLineConfig"; import DeployNodeConfigFormSSHConfig from "./DeployNodeConfigFormSSHConfig.tsx"; import DeployNodeConfigFormTencentCloudCDNConfig from "./DeployNodeConfigFormTencentCloudCDNConfig.tsx"; @@ -273,6 +274,8 @@ const DeployNodeConfigForm = forwardRef; case DEPLOYMENT_PROVIDERS.RAINYUN_RCDN: return ; + case DEPLOYMENT_PROVIDERS.RATPANEL_SITE: + return ; case DEPLOYMENT_PROVIDERS.SAFELINE: return ; case DEPLOYMENT_PROVIDERS.SSH: diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormRatPanelSiteConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormRatPanelSiteConfig.tsx new file mode 100644 index 00000000..03f86913 --- /dev/null +++ b/ui/src/components/workflow/node/DeployNodeConfigFormRatPanelSiteConfig.tsx @@ -0,0 +1,63 @@ +import { useTranslation } from "react-i18next"; +import { Form, type FormInstance, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +type DeployNodeConfigFormRatPanelSiteConfigFieldValues = Nullish<{ + siteName: string; +}>; + +export type DeployNodeConfigFormRatPanelSiteConfigProps = { + form: FormInstance; + formName: string; + disabled?: boolean; + initialValues?: DeployNodeConfigFormRatPanelSiteConfigFieldValues; + onValuesChange?: (values: DeployNodeConfigFormRatPanelSiteConfigFieldValues) => void; +}; + +const initFormModel = (): DeployNodeConfigFormRatPanelSiteConfigFieldValues => { + return { + siteName: "", + }; +}; + +const DeployNodeConfigFormRatPanelSiteConfig = ({ + form: formInst, + formName, + disabled, + initialValues, + onValuesChange, +}: DeployNodeConfigFormRatPanelSiteConfigProps) => { + const { t } = useTranslation(); + + const formSchema = z.object({ + siteName: z.string().nonempty(t("workflow_node.deploy.form.ratpanel_site_name.placeholder")), + }); + const formRule = createSchemaFieldRule(formSchema); + + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); + }; + + return ( +
+ } + > + + +
+ ); +}; + +export default DeployNodeConfigFormRatPanelSiteConfig; diff --git a/ui/src/components/workflow/node/DeployNodeConfigFormSafeLineConfig.tsx b/ui/src/components/workflow/node/DeployNodeConfigFormSafeLineConfig.tsx index 2da3ef16..c5905e14 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigFormSafeLineConfig.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigFormSafeLineConfig.tsx @@ -68,7 +68,12 @@ const DeployNodeConfigFormSafeLineConfig = ({ form: formInst, formName, disabled - + } + > diff --git a/ui/src/domain/access.ts b/ui/src/domain/access.ts index 870b6490..fe912543 100644 --- a/ui/src/domain/access.ts +++ b/ui/src/domain/access.ts @@ -48,6 +48,7 @@ export interface AccessModel extends BaseModel { | AccessConfigForProxmoxVE | AccessConfigForQiniu | AccessConfigForRainYun + | AccessConfigForRatPanel | AccessConfigForSafeLine | AccessConfigForSSH | AccessConfigForSSLCom @@ -293,6 +294,13 @@ export type AccessConfigForRainYun = { apiKey: string; }; +export type AccessConfigForRatPanel = { + apiUrl: string; + accessTokenId: number; + accessToken: string; + allowInsecureConnections?: boolean; +}; + export type AccessConfigForSafeLine = { apiUrl: string; apiToken: string; diff --git a/ui/src/domain/provider.ts b/ui/src/domain/provider.ts index 878814f5..3d0678ba 100644 --- a/ui/src/domain/provider.ts +++ b/ui/src/domain/provider.ts @@ -51,6 +51,7 @@ export const ACCESS_PROVIDERS = Object.freeze({ PROXMOXVE: "proxmoxve", QINIU: "qiniu", RAINYUN: "rainyun", + RATPANEL: "ratpanel", SAFELINE: "safeline", SSH: "ssh", SSLCOM: "sslcom", @@ -120,6 +121,7 @@ export const accessProvidersMap: Map [ diff --git a/ui/src/i18n/locales/en/nls.access.json b/ui/src/i18n/locales/en/nls.access.json index 9ba645cb..b3f9167f 100644 --- a/ui/src/i18n/locales/en/nls.access.json +++ b/ui/src/i18n/locales/en/nls.access.json @@ -313,6 +313,17 @@ "access.form.rainyun_api_key.label": "Rain Yun API key", "access.form.rainyun_api_key.placeholder": "Please enter Rain Yun API key", "access.form.rainyun_api_key.tooltip": "For more information, see https://app.rainyun.com/account/settings/api-key", + "access.form.ratpanel_api_url.label": "RatPanel URL", + "access.form.ratpanel_api_url.placeholder": "Please enter RatPanel URL", + "access.form.ratpanel_access_token_id.label": "RatPanel access token ID", + "access.form.ratpanel_access_token_id.placeholder": "Please enter RatPanel access token ID", + "access.form.ratpanel_access_token_id.tooltip": "For more information, see https://ratpanel.github.io/advanced/api.html", + "access.form.ratpanel_access_token.label": "RatPanel access token", + "access.form.ratpanel_access_token.placeholder": "Please enter RatPanel access token", + "access.form.ratpanel_access_token.tooltip": "For more information, see https://ratpanel.github.io/advanced/api.html", + "access.form.ratpanel_allow_insecure_conns.label": "Insecure SSL/TLS connections", + "access.form.ratpanel_allow_insecure_conns.switch.on": "Allow", + "access.form.ratpanel_allow_insecure_conns.switch.off": "Disallow", "access.form.safeline_api_url.label": "SafeLine URL", "access.form.safeline_api_url.placeholder": "Please enter SafeLine URL", "access.form.safeline_api_token.label": "SafeLine API token", diff --git a/ui/src/i18n/locales/en/nls.provider.json b/ui/src/i18n/locales/en/nls.provider.json index 041f5a63..13571036 100644 --- a/ui/src/i18n/locales/en/nls.provider.json +++ b/ui/src/i18n/locales/en/nls.provider.json @@ -103,6 +103,9 @@ "provider.qiniu.pili": "Qiniu - Pili", "provider.rainyun": "Rain Yun", "provider.rainyun.rcdn": "Rain Yun - RCDN (Rain Content Delivery Network)", + "provider.ratpanel": "RatPanel", + "provider.ratpanel.console": "RatPanel - Console", + "provider.ratpanel.site": "RatPanel - Website", "provider.safeline": "SafeLine", "provider.ssh": "SSH deployment", "provider.sslcom": "SSL.com", @@ -150,8 +153,10 @@ "provider.category.loadbalance": "Loadbalance", "provider.category.firewall": "Firewall", "provider.category.av": "Audio/Video", + "provider.category.apigw": "API Gateway", "provider.category.serverless": "Serverless", "provider.category.website": "Website", + "provider.category.ssl": "SSL", "provider.category.nas": "NAS", "provider.category.other": "Other", diff --git a/ui/src/i18n/locales/en/nls.workflow.nodes.json b/ui/src/i18n/locales/en/nls.workflow.nodes.json index fce606e5..006979f1 100644 --- a/ui/src/i18n/locales/en/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/en/nls.workflow.nodes.json @@ -325,7 +325,7 @@ "workflow_node.deploy.form.baotapanel_site_type.option.other.label": "Other sites", "workflow_node.deploy.form.baotapanel_site_name.label": "aaPanel site name", "workflow_node.deploy.form.baotapanel_site_name.placeholder": "Please enter aaPanel site name", - "workflow_node.deploy.form.baotapanel_site_name.tooltip": "Usually equal to the website domain name.", + "workflow_node.deploy.form.baotapanel_site_name.tooltip": "You can find it on aaPanel WebUI.", "workflow_node.deploy.form.baotapanel_site_names.label": "aaPanel site names", "workflow_node.deploy.form.baotapanel_site_names.placeholder": "Please enter aaPanel site names (separated by semicolons)", "workflow_node.deploy.form.baotapanel_site_names.errmsg.invalid": "Please enter a valid aaPanel site name", @@ -513,11 +513,15 @@ "workflow_node.deploy.form.rainyun_rcdn_domain.label": "Rain Yun RCDN domain", "workflow_node.deploy.form.rainyun_rcdn_domain.placeholder": "Please enter Rain Yun RCDN domain name", "workflow_node.deploy.form.rainyun_rcdn_domain.tooltip": "For more information, see https://app.rainyun.com/apps/rcdn/list", + "workflow_node.deploy.form.ratpanel_site_name.label": "RatPanel site name", + "workflow_node.deploy.form.ratpanel_site_name.placeholder": "Please enter RatPanel site name", + "workflow_node.deploy.form.ratpanel_site_name.tooltip": "You can find it on RatPanel WebUI.", "workflow_node.deploy.form.safeline_resource_type.label": "Resource type", "workflow_node.deploy.form.safeline_resource_type.placeholder": "Please select resource type", "workflow_node.deploy.form.safeline_resource_type.option.certificate.label": "Certificate", "workflow_node.deploy.form.safeline_certificate_id.label": "SafeLine certificate ID", "workflow_node.deploy.form.safeline_certificate_id.placeholder": "Please enter SafeLine certificate ID", + "workflow_node.deploy.form.safeline_certificate_id.tooltip": "You can find it on SafeLine WebUI.", "workflow_node.deploy.form.ssh_format.label": "File format", "workflow_node.deploy.form.ssh_format.placeholder": "Please select file format", "workflow_node.deploy.form.ssh_format.option.pem.label": "PEM (*.pem, *.crt, *.key)", diff --git a/ui/src/i18n/locales/zh/nls.access.json b/ui/src/i18n/locales/zh/nls.access.json index 04af883a..5e3444fe 100644 --- a/ui/src/i18n/locales/zh/nls.access.json +++ b/ui/src/i18n/locales/zh/nls.access.json @@ -307,6 +307,17 @@ "access.form.rainyun_api_key.label": "雨云 API 密钥", "access.form.rainyun_api_key.placeholder": "请输入雨云 API 密钥", "access.form.rainyun_api_key.tooltip": "这是什么?请参阅 https://app.rainyun.com/account/settings/api-key", + "access.form.ratpanel_api_url.label": "耗子面板 URL", + "access.form.ratpanel_api_url.placeholder": "请输入耗子面板 URL", + "access.form.ratpanel_access_token_id.label": "耗子面板 AccessToken ID", + "access.form.ratpanel_access_token_id.placeholder": "请输入耗子面板 AccessToken ID", + "access.form.ratpanel_access_token_id.tooltip": "这是什么?请参阅 https://ratpanel.github.io/advanced/api.html", + "access.form.ratpanel_access_token.label": "耗子面板 AccessToken", + "access.form.ratpanel_access_token.placeholder": "请输入耗子面板 AccessToken", + "access.form.ratpanel_access_token.tooltip": "这是什么?请参阅 https://ratpanel.github.io/advanced/api.html", + "access.form.ratpanel_allow_insecure_conns.label": "忽略 SSL/TLS 证书错误", + "access.form.ratpanel_allow_insecure_conns.switch.on": "允许", + "access.form.ratpanel_allow_insecure_conns.switch.off": "不允许", "access.form.safeline_api_url.label": "雷池 URL", "access.form.safeline_api_url.placeholder": "请输入雷池 URL", "access.form.safeline_api_token.label": "雷池 API Token", diff --git a/ui/src/i18n/locales/zh/nls.provider.json b/ui/src/i18n/locales/zh/nls.provider.json index e9ff69e0..bd04cc43 100644 --- a/ui/src/i18n/locales/zh/nls.provider.json +++ b/ui/src/i18n/locales/zh/nls.provider.json @@ -103,6 +103,9 @@ "provider.qiniu.pili": "七牛云 - 视频直播 Pili", "provider.rainyun": "雨云", "provider.rainyun.rcdn": "雨云 - 雨盾 CDN", + "provider.ratpanel": "耗子面板", + "provider.ratpanel.console": "耗子面板 - 面板", + "provider.ratpanel.site": "耗子面板 - 网站", "provider.safeline": "雷池", "provider.ssh": "SSH 部署", "provider.sslcom": "SSL.com", @@ -150,8 +153,10 @@ "provider.category.loadbalance": "负载均衡", "provider.category.firewall": "防火墙", "provider.category.av": "音视频", + "provider.category.apigw": "API 网关", "provider.category.serverless": "Serverless", "provider.category.website": "网站托管", + "provider.category.ssl": "证书托管", "provider.category.nas": "NAS", "provider.category.other": "其他", diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json index b7992acf..acc5657f 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json @@ -115,10 +115,10 @@ "workflow_node.deploy.form.1panel_site_resource_type.option.certificate.label": "替换指定证书", "workflow_node.deploy.form.1panel_site_website_id.label": "1Panel 网站 ID", "workflow_node.deploy.form.1panel_site_website_id.placeholder": "请输入 1Panel 网站 ID", - "workflow_node.deploy.form.1panel_site_website_id.tooltip": "请在 1Panel 管理面板查看。", + "workflow_node.deploy.form.1panel_site_website_id.tooltip": "请登录 1Panel 管理面板查看。", "workflow_node.deploy.form.1panel_site_certificate_id.label": "1Panel 证书 ID", "workflow_node.deploy.form.1panel_site_certificate_id.placeholder": "请输入 1Panel 证书 ID", - "workflow_node.deploy.form.1panel_site_certificate_id.tooltip": "请在 1Panel 管理面板查看。", + "workflow_node.deploy.form.1panel_site_certificate_id.tooltip": "请登录 1Panel 管理面板查看。", "workflow_node.deploy.form.aliyun_alb_resource_type.label": "证书替换方式", "workflow_node.deploy.form.aliyun_alb_resource_type.placeholder": "请选择证书替换方式", "workflow_node.deploy.form.aliyun_alb_resource_type.option.loadbalancer.label": "替换指定负载均衡器下的全部 HTTPS/QUIC 监听的证书", @@ -324,7 +324,7 @@ "workflow_node.deploy.form.baotapanel_site_type.option.other.label": "其他", "workflow_node.deploy.form.baotapanel_site_name.label": "宝塔面板网站名称", "workflow_node.deploy.form.baotapanel_site_name.placeholder": "请输入宝塔面板网站名称", - "workflow_node.deploy.form.baotapanel_site_name.tooltip": "通常为网站域名。", + "workflow_node.deploy.form.baotapanel_site_name.tooltip": "请登录宝塔面板查看", "workflow_node.deploy.form.baotapanel_site_names.label": "宝塔面板网站名称", "workflow_node.deploy.form.baotapanel_site_names.placeholder": "请输入宝塔面板网站名称(多个值请用半角分号隔开)", "workflow_node.deploy.form.baotapanel_site_names.errmsg.invalid": "请输入正确的宝塔面板网站名称", @@ -512,11 +512,15 @@ "workflow_node.deploy.form.rainyun_rcdn_domain.label": "雨云 RCDN 加速域名", "workflow_node.deploy.form.rainyun_rcdn_domain.placeholder": "请输入雨云 RCDN 加速域名(支持泛域名)", "workflow_node.deploy.form.rainyun_rcdn_domain.tooltip": "这是什么?请参阅 https://app.rainyun.com/apps/rcdn/list", + "workflow_node.deploy.form.ratpanel_site_name.label": "耗子面板网站名称", + "workflow_node.deploy.form.ratpanel_site_name.placeholder": "请输入耗子面板网站名称", + "workflow_node.deploy.form.ratpanel_site_name.tooltip": "请登录耗子面板查看。", "workflow_node.deploy.form.safeline_resource_type.label": "证书替换方式", "workflow_node.deploy.form.safeline_resource_type.placeholder": "请选择证书替换方式", "workflow_node.deploy.form.safeline_resource_type.option.certificate.label": "替换指定证书", "workflow_node.deploy.form.safeline_certificate_id.label": "雷池证书 ID", "workflow_node.deploy.form.safeline_certificate_id.placeholder": "请输入雷池证书 ID", + "workflow_node.deploy.form.safeline_certificate_id.tooltip": "请登录雷池控制台查看。", "workflow_node.deploy.form.ssh_format.label": "文件格式", "workflow_node.deploy.form.ssh_format.placeholder": "请选择文件格式", "workflow_node.deploy.form.ssh_format.option.pem.label": "PEM 格式(*.pem, *.crt, *.key)",