mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-08 05:29:51 +00:00
feat: support 1panel v2
This commit is contained in:
parent
06fd95782a
commit
fd875feef3
@ -111,6 +111,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
|
|||||||
case domain.DeploymentProviderType1PanelConsole:
|
case domain.DeploymentProviderType1PanelConsole:
|
||||||
deployer, err := p1PanelConsole.NewDeployer(&p1PanelConsole.DeployerConfig{
|
deployer, err := p1PanelConsole.NewDeployer(&p1PanelConsole.DeployerConfig{
|
||||||
ApiUrl: access.ApiUrl,
|
ApiUrl: access.ApiUrl,
|
||||||
|
ApiVersion: access.ApiVersion,
|
||||||
ApiKey: access.ApiKey,
|
ApiKey: access.ApiKey,
|
||||||
AllowInsecureConnections: access.AllowInsecureConnections,
|
AllowInsecureConnections: access.AllowInsecureConnections,
|
||||||
AutoRestart: maputil.GetBool(options.ProviderExtendedConfig, "autoRestart"),
|
AutoRestart: maputil.GetBool(options.ProviderExtendedConfig, "autoRestart"),
|
||||||
@ -120,6 +121,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
|
|||||||
case domain.DeploymentProviderType1PanelSite:
|
case domain.DeploymentProviderType1PanelSite:
|
||||||
deployer, err := p1PanelSite.NewDeployer(&p1PanelSite.DeployerConfig{
|
deployer, err := p1PanelSite.NewDeployer(&p1PanelSite.DeployerConfig{
|
||||||
ApiUrl: access.ApiUrl,
|
ApiUrl: access.ApiUrl,
|
||||||
|
ApiVersion: access.ApiVersion,
|
||||||
ApiKey: access.ApiKey,
|
ApiKey: access.ApiKey,
|
||||||
AllowInsecureConnections: access.AllowInsecureConnections,
|
AllowInsecureConnections: access.AllowInsecureConnections,
|
||||||
ResourceType: p1PanelSite.ResourceType(maputil.GetOrDefaultString(options.ProviderExtendedConfig, "resourceType", string(p1PanelSite.RESOURCE_TYPE_WEBSITE))),
|
ResourceType: p1PanelSite.ResourceType(maputil.GetOrDefaultString(options.ProviderExtendedConfig, "resourceType", string(p1PanelSite.RESOURCE_TYPE_WEBSITE))),
|
||||||
|
@ -17,6 +17,7 @@ type Access struct {
|
|||||||
|
|
||||||
type AccessConfigFor1Panel struct {
|
type AccessConfigFor1Panel struct {
|
||||||
ApiUrl string `json:"apiUrl"`
|
ApiUrl string `json:"apiUrl"`
|
||||||
|
ApiVersion string `json:"apiVersion"`
|
||||||
ApiKey string `json:"apiKey"`
|
ApiKey string `json:"apiKey"`
|
||||||
AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"`
|
AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"`
|
||||||
}
|
}
|
||||||
|
@ -9,12 +9,14 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/usual2970/certimate/internal/pkg/core/deployer"
|
"github.com/usual2970/certimate/internal/pkg/core/deployer"
|
||||||
opsdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/1panel"
|
onepanelsdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/1panel"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DeployerConfig struct {
|
type DeployerConfig struct {
|
||||||
// 1Panel 地址。
|
// 1Panel 地址。
|
||||||
ApiUrl string `json:"apiUrl"`
|
ApiUrl string `json:"apiUrl"`
|
||||||
|
// 1Panel 版本。
|
||||||
|
ApiVersion string `json:"apiVersion"`
|
||||||
// 1Panel 接口密钥。
|
// 1Panel 接口密钥。
|
||||||
ApiKey string `json:"apiKey"`
|
ApiKey string `json:"apiKey"`
|
||||||
// 是否允许不安全的连接。
|
// 是否允许不安全的连接。
|
||||||
@ -26,7 +28,7 @@ type DeployerConfig struct {
|
|||||||
type DeployerProvider struct {
|
type DeployerProvider struct {
|
||||||
config *DeployerConfig
|
config *DeployerConfig
|
||||||
logger *slog.Logger
|
logger *slog.Logger
|
||||||
sdkClient *opsdk.Client
|
sdkClient *onepanelsdk.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ deployer.Deployer = (*DeployerProvider)(nil)
|
var _ deployer.Deployer = (*DeployerProvider)(nil)
|
||||||
@ -36,7 +38,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
|
|||||||
panic("config is nil")
|
panic("config is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := createSdkClient(config.ApiUrl, config.ApiKey, config.AllowInsecureConnections)
|
client, err := createSdkClient(config.ApiUrl, config.ApiVersion, config.ApiKey, config.AllowInsecureConnections)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create sdk client: %w", err)
|
return nil, fmt.Errorf("failed to create sdk client: %w", err)
|
||||||
}
|
}
|
||||||
@ -59,7 +61,7 @@ func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
|
|||||||
|
|
||||||
func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPEM string) (*deployer.DeployResult, error) {
|
func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPEM string) (*deployer.DeployResult, error) {
|
||||||
// 设置面板 SSL 证书
|
// 设置面板 SSL 证书
|
||||||
updateSystemSSLReq := &opsdk.UpdateSystemSSLRequest{
|
updateSystemSSLReq := &onepanelsdk.UpdateSystemSSLRequest{
|
||||||
Cert: certPEM,
|
Cert: certPEM,
|
||||||
Key: privkeyPEM,
|
Key: privkeyPEM,
|
||||||
SSL: "enable",
|
SSL: "enable",
|
||||||
@ -79,16 +81,20 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
|
|||||||
return &deployer.DeployResult{}, nil
|
return &deployer.DeployResult{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createSdkClient(apiUrl, apiKey string, skipTlsVerify bool) (*opsdk.Client, error) {
|
func createSdkClient(apiUrl, apiVersion, apiKey string, skipTlsVerify bool) (*onepanelsdk.Client, error) {
|
||||||
if _, err := url.Parse(apiUrl); err != nil {
|
if _, err := url.Parse(apiUrl); err != nil {
|
||||||
return nil, errors.New("invalid 1panel api url")
|
return nil, errors.New("invalid 1panel api url")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if apiVersion == "" {
|
||||||
|
return nil, errors.New("invalid 1panel api version")
|
||||||
|
}
|
||||||
|
|
||||||
if apiKey == "" {
|
if apiKey == "" {
|
||||||
return nil, errors.New("invalid 1panel api key")
|
return nil, errors.New("invalid 1panel api key")
|
||||||
}
|
}
|
||||||
|
|
||||||
client := opsdk.NewClient(apiUrl, apiKey)
|
client := onepanelsdk.NewClient(apiUrl, apiVersion, apiKey)
|
||||||
if skipTlsVerify {
|
if skipTlsVerify {
|
||||||
client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true})
|
client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true})
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ var (
|
|||||||
fInputCertPath string
|
fInputCertPath string
|
||||||
fInputKeyPath string
|
fInputKeyPath string
|
||||||
fApiUrl string
|
fApiUrl string
|
||||||
|
fApiVersion string
|
||||||
fApiKey string
|
fApiKey string
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -24,6 +25,7 @@ func init() {
|
|||||||
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
|
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
|
||||||
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
|
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
|
||||||
flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "")
|
flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "")
|
||||||
|
flag.StringVar(&fApiVersion, argsPrefix+"APIVERSION", "v1", "")
|
||||||
flag.StringVar(&fApiKey, argsPrefix+"APIKEY", "", "")
|
flag.StringVar(&fApiKey, argsPrefix+"APIKEY", "", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +36,7 @@ Shell command to run this test:
|
|||||||
--CERTIMATE_DEPLOYER_1PANELCONSOLE_INPUTCERTPATH="/path/to/your-input-cert.pem" \
|
--CERTIMATE_DEPLOYER_1PANELCONSOLE_INPUTCERTPATH="/path/to/your-input-cert.pem" \
|
||||||
--CERTIMATE_DEPLOYER_1PANELCONSOLE_INPUTKEYPATH="/path/to/your-input-key.pem" \
|
--CERTIMATE_DEPLOYER_1PANELCONSOLE_INPUTKEYPATH="/path/to/your-input-key.pem" \
|
||||||
--CERTIMATE_DEPLOYER_1PANELCONSOLE_APIURL="http://127.0.0.1:20410" \
|
--CERTIMATE_DEPLOYER_1PANELCONSOLE_APIURL="http://127.0.0.1:20410" \
|
||||||
|
--CERTIMATE_DEPLOYER_1PANELCONSOLE_APIVERSION="v1" \
|
||||||
--CERTIMATE_DEPLOYER_1PANELCONSOLE_APIKEY="your-api-key"
|
--CERTIMATE_DEPLOYER_1PANELCONSOLE_APIKEY="your-api-key"
|
||||||
*/
|
*/
|
||||||
func TestDeploy(t *testing.T) {
|
func TestDeploy(t *testing.T) {
|
||||||
@ -45,11 +48,13 @@ func TestDeploy(t *testing.T) {
|
|||||||
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
|
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
|
||||||
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
|
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
|
||||||
fmt.Sprintf("APIURL: %v", fApiUrl),
|
fmt.Sprintf("APIURL: %v", fApiUrl),
|
||||||
|
fmt.Sprintf("APIVERSION: %v", fApiVersion),
|
||||||
fmt.Sprintf("APIKEY: %v", fApiKey),
|
fmt.Sprintf("APIKEY: %v", fApiKey),
|
||||||
}, "\n"))
|
}, "\n"))
|
||||||
|
|
||||||
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
|
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
|
||||||
ApiUrl: fApiUrl,
|
ApiUrl: fApiUrl,
|
||||||
|
ApiVersion: fApiVersion,
|
||||||
ApiKey: fApiKey,
|
ApiKey: fApiKey,
|
||||||
AllowInsecureConnections: true,
|
AllowInsecureConnections: true,
|
||||||
AutoRestart: true,
|
AutoRestart: true,
|
||||||
|
@ -12,12 +12,14 @@ import (
|
|||||||
"github.com/usual2970/certimate/internal/pkg/core/deployer"
|
"github.com/usual2970/certimate/internal/pkg/core/deployer"
|
||||||
"github.com/usual2970/certimate/internal/pkg/core/uploader"
|
"github.com/usual2970/certimate/internal/pkg/core/uploader"
|
||||||
uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/1panel-ssl"
|
uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/1panel-ssl"
|
||||||
opsdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/1panel"
|
onepanelsdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/1panel"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DeployerConfig struct {
|
type DeployerConfig struct {
|
||||||
// 1Panel 地址。
|
// 1Panel 地址。
|
||||||
ApiUrl string `json:"apiUrl"`
|
ApiUrl string `json:"apiUrl"`
|
||||||
|
// 1Panel 版本。
|
||||||
|
ApiVersion string `json:"apiVersion"`
|
||||||
// 1Panel 接口密钥。
|
// 1Panel 接口密钥。
|
||||||
ApiKey string `json:"apiKey"`
|
ApiKey string `json:"apiKey"`
|
||||||
// 是否允许不安全的连接。
|
// 是否允许不安全的连接。
|
||||||
@ -35,7 +37,7 @@ type DeployerConfig struct {
|
|||||||
type DeployerProvider struct {
|
type DeployerProvider struct {
|
||||||
config *DeployerConfig
|
config *DeployerConfig
|
||||||
logger *slog.Logger
|
logger *slog.Logger
|
||||||
sdkClient *opsdk.Client
|
sdkClient *onepanelsdk.Client
|
||||||
sslUploader uploader.Uploader
|
sslUploader uploader.Uploader
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,14 +48,15 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
|
|||||||
panic("config is nil")
|
panic("config is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := createSdkClient(config.ApiUrl, config.ApiKey, config.AllowInsecureConnections)
|
client, err := createSdkClient(config.ApiUrl, config.ApiVersion, config.ApiKey, config.AllowInsecureConnections)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create sdk client: %w", err)
|
return nil, fmt.Errorf("failed to create sdk client: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
|
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
|
||||||
ApiUrl: config.ApiUrl,
|
ApiUrl: config.ApiUrl,
|
||||||
ApiKey: config.ApiKey,
|
ApiVersion: config.ApiVersion,
|
||||||
|
ApiKey: config.ApiKey,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
|
return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
|
||||||
@ -103,7 +106,7 @@ func (d *DeployerProvider) deployToWebsite(ctx context.Context, certPEM string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取网站 HTTPS 配置
|
// 获取网站 HTTPS 配置
|
||||||
getHttpsConfReq := &opsdk.GetHttpsConfRequest{
|
getHttpsConfReq := &onepanelsdk.GetHttpsConfRequest{
|
||||||
WebsiteID: d.config.WebsiteId,
|
WebsiteID: d.config.WebsiteId,
|
||||||
}
|
}
|
||||||
getHttpsConfResp, err := d.sdkClient.GetHttpsConf(getHttpsConfReq)
|
getHttpsConfResp, err := d.sdkClient.GetHttpsConf(getHttpsConfReq)
|
||||||
@ -122,7 +125,7 @@ func (d *DeployerProvider) deployToWebsite(ctx context.Context, certPEM string,
|
|||||||
|
|
||||||
// 修改网站 HTTPS 配置
|
// 修改网站 HTTPS 配置
|
||||||
certId, _ := strconv.ParseInt(upres.CertId, 10, 64)
|
certId, _ := strconv.ParseInt(upres.CertId, 10, 64)
|
||||||
updateHttpsConfReq := &opsdk.UpdateHttpsConfRequest{
|
updateHttpsConfReq := &onepanelsdk.UpdateHttpsConfRequest{
|
||||||
WebsiteID: d.config.WebsiteId,
|
WebsiteID: d.config.WebsiteId,
|
||||||
Type: "existed",
|
Type: "existed",
|
||||||
WebsiteSSLID: certId,
|
WebsiteSSLID: certId,
|
||||||
@ -147,7 +150,7 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取证书详情
|
// 获取证书详情
|
||||||
getWebsiteSSLReq := &opsdk.GetWebsiteSSLRequest{
|
getWebsiteSSLReq := &onepanelsdk.GetWebsiteSSLRequest{
|
||||||
SSLID: d.config.CertificateId,
|
SSLID: d.config.CertificateId,
|
||||||
}
|
}
|
||||||
getWebsiteSSLResp, err := d.sdkClient.GetWebsiteSSL(getWebsiteSSLReq)
|
getWebsiteSSLResp, err := d.sdkClient.GetWebsiteSSL(getWebsiteSSLReq)
|
||||||
@ -157,7 +160,7 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 更新证书
|
// 更新证书
|
||||||
uploadWebsiteSSLReq := &opsdk.UploadWebsiteSSLRequest{
|
uploadWebsiteSSLReq := &onepanelsdk.UploadWebsiteSSLRequest{
|
||||||
Type: "paste",
|
Type: "paste",
|
||||||
SSLID: d.config.CertificateId,
|
SSLID: d.config.CertificateId,
|
||||||
Description: getWebsiteSSLResp.Data.Description,
|
Description: getWebsiteSSLResp.Data.Description,
|
||||||
@ -173,16 +176,20 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createSdkClient(apiUrl, apiKey string, skipTlsVerify bool) (*opsdk.Client, error) {
|
func createSdkClient(apiUrl, apiVersion, apiKey string, skipTlsVerify bool) (*onepanelsdk.Client, error) {
|
||||||
if _, err := url.Parse(apiUrl); err != nil {
|
if _, err := url.Parse(apiUrl); err != nil {
|
||||||
return nil, errors.New("invalid 1panel api url")
|
return nil, errors.New("invalid 1panel api url")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if apiVersion == "" {
|
||||||
|
return nil, errors.New("invalid 1panel api version")
|
||||||
|
}
|
||||||
|
|
||||||
if apiKey == "" {
|
if apiKey == "" {
|
||||||
return nil, errors.New("invalid 1panel api key")
|
return nil, errors.New("invalid 1panel api key")
|
||||||
}
|
}
|
||||||
|
|
||||||
client := opsdk.NewClient(apiUrl, apiKey)
|
client := onepanelsdk.NewClient(apiUrl, apiVersion, apiKey)
|
||||||
if skipTlsVerify {
|
if skipTlsVerify {
|
||||||
client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true})
|
client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true})
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ var (
|
|||||||
fInputCertPath string
|
fInputCertPath string
|
||||||
fInputKeyPath string
|
fInputKeyPath string
|
||||||
fApiUrl string
|
fApiUrl string
|
||||||
|
fApiVersion string
|
||||||
fApiKey string
|
fApiKey string
|
||||||
fWebsiteId int64
|
fWebsiteId int64
|
||||||
)
|
)
|
||||||
@ -25,6 +26,7 @@ func init() {
|
|||||||
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
|
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
|
||||||
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
|
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
|
||||||
flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "")
|
flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "")
|
||||||
|
flag.StringVar(&fApiVersion, argsPrefix+"APIVERSION", "v1", "")
|
||||||
flag.StringVar(&fApiKey, argsPrefix+"APIKEY", "", "")
|
flag.StringVar(&fApiKey, argsPrefix+"APIKEY", "", "")
|
||||||
flag.Int64Var(&fWebsiteId, argsPrefix+"WEBSITEID", 0, "")
|
flag.Int64Var(&fWebsiteId, argsPrefix+"WEBSITEID", 0, "")
|
||||||
}
|
}
|
||||||
@ -36,6 +38,7 @@ Shell command to run this test:
|
|||||||
--CERTIMATE_DEPLOYER_1PANELSITE_INPUTCERTPATH="/path/to/your-input-cert.pem" \
|
--CERTIMATE_DEPLOYER_1PANELSITE_INPUTCERTPATH="/path/to/your-input-cert.pem" \
|
||||||
--CERTIMATE_DEPLOYER_1PANELSITE_INPUTKEYPATH="/path/to/your-input-key.pem" \
|
--CERTIMATE_DEPLOYER_1PANELSITE_INPUTKEYPATH="/path/to/your-input-key.pem" \
|
||||||
--CERTIMATE_DEPLOYER_1PANELSITE_APIURL="http://127.0.0.1:20410" \
|
--CERTIMATE_DEPLOYER_1PANELSITE_APIURL="http://127.0.0.1:20410" \
|
||||||
|
--CERTIMATE_DEPLOYER_1PANELSITE_APIVERSION="v1" \
|
||||||
--CERTIMATE_DEPLOYER_1PANELSITE_APIKEY="your-api-key" \
|
--CERTIMATE_DEPLOYER_1PANELSITE_APIKEY="your-api-key" \
|
||||||
--CERTIMATE_DEPLOYER_1PANELSITE_WEBSITEID="your-website-id"
|
--CERTIMATE_DEPLOYER_1PANELSITE_WEBSITEID="your-website-id"
|
||||||
*/
|
*/
|
||||||
@ -48,12 +51,14 @@ func TestDeploy(t *testing.T) {
|
|||||||
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
|
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
|
||||||
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
|
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
|
||||||
fmt.Sprintf("APIURL: %v", fApiUrl),
|
fmt.Sprintf("APIURL: %v", fApiUrl),
|
||||||
|
fmt.Sprintf("APIVERSION: %v", fApiVersion),
|
||||||
fmt.Sprintf("APIKEY: %v", fApiKey),
|
fmt.Sprintf("APIKEY: %v", fApiKey),
|
||||||
fmt.Sprintf("WEBSITEID: %v", fWebsiteId),
|
fmt.Sprintf("WEBSITEID: %v", fWebsiteId),
|
||||||
}, "\n"))
|
}, "\n"))
|
||||||
|
|
||||||
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
|
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
|
||||||
ApiUrl: fApiUrl,
|
ApiUrl: fApiUrl,
|
||||||
|
ApiVersion: fApiVersion,
|
||||||
ApiKey: fApiKey,
|
ApiKey: fApiKey,
|
||||||
AllowInsecureConnections: true,
|
AllowInsecureConnections: true,
|
||||||
ResourceType: provider.RESOURCE_TYPE_WEBSITE,
|
ResourceType: provider.RESOURCE_TYPE_WEBSITE,
|
||||||
|
@ -10,12 +10,14 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/usual2970/certimate/internal/pkg/core/uploader"
|
"github.com/usual2970/certimate/internal/pkg/core/uploader"
|
||||||
opsdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/1panel"
|
onepanelsdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/1panel"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UploaderConfig struct {
|
type UploaderConfig struct {
|
||||||
// 1Panel 地址。
|
// 1Panel 地址。
|
||||||
ApiUrl string `json:"apiUrl"`
|
ApiUrl string `json:"apiUrl"`
|
||||||
|
// 1Panel 版本。
|
||||||
|
ApiVersion string `json:"apiVersion"`
|
||||||
// 1Panel 接口密钥。
|
// 1Panel 接口密钥。
|
||||||
ApiKey string `json:"apiKey"`
|
ApiKey string `json:"apiKey"`
|
||||||
}
|
}
|
||||||
@ -23,7 +25,7 @@ type UploaderConfig struct {
|
|||||||
type UploaderProvider struct {
|
type UploaderProvider struct {
|
||||||
config *UploaderConfig
|
config *UploaderConfig
|
||||||
logger *slog.Logger
|
logger *slog.Logger
|
||||||
sdkClient *opsdk.Client
|
sdkClient *onepanelsdk.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ uploader.Uploader = (*UploaderProvider)(nil)
|
var _ uploader.Uploader = (*UploaderProvider)(nil)
|
||||||
@ -33,7 +35,7 @@ func NewUploader(config *UploaderConfig) (*UploaderProvider, error) {
|
|||||||
panic("config is nil")
|
panic("config is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := createSdkClient(config.ApiUrl, config.ApiKey)
|
client, err := createSdkClient(config.ApiUrl, config.ApiVersion, config.ApiKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create sdk client: %w", err)
|
return nil, fmt.Errorf("failed to create sdk client: %w", err)
|
||||||
}
|
}
|
||||||
@ -67,7 +69,7 @@ func (u *UploaderProvider) Upload(ctx context.Context, certPEM string, privkeyPE
|
|||||||
certName := fmt.Sprintf("certimate-%d", time.Now().UnixMilli())
|
certName := fmt.Sprintf("certimate-%d", time.Now().UnixMilli())
|
||||||
|
|
||||||
// 上传证书
|
// 上传证书
|
||||||
uploadWebsiteSSLReq := &opsdk.UploadWebsiteSSLRequest{
|
uploadWebsiteSSLReq := &onepanelsdk.UploadWebsiteSSLRequest{
|
||||||
Type: "paste",
|
Type: "paste",
|
||||||
Description: certName,
|
Description: certName,
|
||||||
Certificate: certPEM,
|
Certificate: certPEM,
|
||||||
@ -99,7 +101,7 @@ func (u *UploaderProvider) getCertIfExists(ctx context.Context, certPEM string,
|
|||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
searchWebsiteSSLReq := &opsdk.SearchWebsiteSSLRequest{
|
searchWebsiteSSLReq := &onepanelsdk.SearchWebsiteSSLRequest{
|
||||||
Page: searchWebsiteSSLPageNumber,
|
Page: searchWebsiteSSLPageNumber,
|
||||||
PageSize: searchWebsiteSSLPageSize,
|
PageSize: searchWebsiteSSLPageSize,
|
||||||
}
|
}
|
||||||
@ -130,15 +132,19 @@ func (u *UploaderProvider) getCertIfExists(ctx context.Context, certPEM string,
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createSdkClient(apiUrl, apiKey string) (*opsdk.Client, error) {
|
func createSdkClient(apiUrl, apiVersion, apiKey string) (*onepanelsdk.Client, error) {
|
||||||
if _, err := url.Parse(apiUrl); err != nil {
|
if _, err := url.Parse(apiUrl); err != nil {
|
||||||
return nil, errors.New("invalid 1panel api url")
|
return nil, errors.New("invalid 1panel api url")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if apiVersion == "" {
|
||||||
|
return nil, errors.New("invalid 1panel api version")
|
||||||
|
}
|
||||||
|
|
||||||
if apiKey == "" {
|
if apiKey == "" {
|
||||||
return nil, errors.New("invalid 1panel api key")
|
return nil, errors.New("invalid 1panel api key")
|
||||||
}
|
}
|
||||||
|
|
||||||
client := opsdk.NewClient(apiUrl, apiKey)
|
client := onepanelsdk.NewClient(apiUrl, apiVersion, apiKey)
|
||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ var (
|
|||||||
fInputCertPath string
|
fInputCertPath string
|
||||||
fInputKeyPath string
|
fInputKeyPath string
|
||||||
fApiUrl string
|
fApiUrl string
|
||||||
|
fApiVersion string
|
||||||
fApiKey string
|
fApiKey string
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -25,6 +26,7 @@ func init() {
|
|||||||
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
|
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
|
||||||
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
|
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
|
||||||
flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "")
|
flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "")
|
||||||
|
flag.StringVar(&fApiVersion, argsPrefix+"APIVERSION", "v1", "")
|
||||||
flag.StringVar(&fApiKey, argsPrefix+"APIKEY", "", "")
|
flag.StringVar(&fApiKey, argsPrefix+"APIKEY", "", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,6 +37,7 @@ Shell command to run this test:
|
|||||||
--CERTIMATE_UPLOADER_1PANELSSL_INPUTCERTPATH="/path/to/your-input-cert.pem" \
|
--CERTIMATE_UPLOADER_1PANELSSL_INPUTCERTPATH="/path/to/your-input-cert.pem" \
|
||||||
--CERTIMATE_UPLOADER_1PANELSSL_INPUTKEYPATH="/path/to/your-input-key.pem" \
|
--CERTIMATE_UPLOADER_1PANELSSL_INPUTKEYPATH="/path/to/your-input-key.pem" \
|
||||||
--CERTIMATE_UPLOADER_1PANELSSL_APIURL="http://127.0.0.1:20410" \
|
--CERTIMATE_UPLOADER_1PANELSSL_APIURL="http://127.0.0.1:20410" \
|
||||||
|
--CERTIMATE_UPLOADER_1PANELSSL_APIVERSION="v1" \
|
||||||
--CERTIMATE_UPLOADER_1PANELSSL_APIKEY="your-api-key"
|
--CERTIMATE_UPLOADER_1PANELSSL_APIKEY="your-api-key"
|
||||||
*/
|
*/
|
||||||
func TestDeploy(t *testing.T) {
|
func TestDeploy(t *testing.T) {
|
||||||
@ -46,12 +49,14 @@ func TestDeploy(t *testing.T) {
|
|||||||
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
|
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
|
||||||
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
|
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
|
||||||
fmt.Sprintf("APIURL: %v", fApiUrl),
|
fmt.Sprintf("APIURL: %v", fApiUrl),
|
||||||
|
fmt.Sprintf("APIVERSION: %v", fApiVersion),
|
||||||
fmt.Sprintf("APIKEY: %v", fApiKey),
|
fmt.Sprintf("APIKEY: %v", fApiKey),
|
||||||
}, "\n"))
|
}, "\n"))
|
||||||
|
|
||||||
uploader, err := provider.NewUploader(&provider.UploaderConfig{
|
uploader, err := provider.NewUploader(&provider.UploaderConfig{
|
||||||
ApiUrl: fApiUrl,
|
ApiUrl: fApiUrl,
|
||||||
ApiKey: fApiKey,
|
ApiVersion: fApiVersion,
|
||||||
|
ApiKey: fApiKey,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("err: %+v", err)
|
t.Errorf("err: %+v", err)
|
||||||
|
@ -14,19 +14,25 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
apiHost string
|
apiHost string
|
||||||
apiKey string
|
apiVersion string
|
||||||
|
apiKey string
|
||||||
|
|
||||||
client *resty.Client
|
client *resty.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient(apiHost, apiKey string) *Client {
|
func NewClient(apiHost, apiVersion, apiKey string) *Client {
|
||||||
client := resty.New()
|
client := resty.New()
|
||||||
|
|
||||||
|
if apiVersion == "" {
|
||||||
|
apiVersion = "v1"
|
||||||
|
}
|
||||||
|
|
||||||
return &Client{
|
return &Client{
|
||||||
apiHost: strings.TrimRight(apiHost, "/"),
|
apiHost: strings.TrimRight(apiHost, "/"),
|
||||||
apiKey: apiKey,
|
apiVersion: apiVersion,
|
||||||
client: client,
|
apiKey: apiKey,
|
||||||
|
client: client,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +55,7 @@ func (c *Client) generateToken(timestamp string) string {
|
|||||||
func (c *Client) sendRequest(method string, path string, params interface{}) (*resty.Response, error) {
|
func (c *Client) sendRequest(method string, path string, params interface{}) (*resty.Response, error) {
|
||||||
req := c.client.R()
|
req := c.client.R()
|
||||||
req.Method = method
|
req.Method = method
|
||||||
req.URL = c.apiHost + "/api/v1" + path
|
req.URL = c.apiHost + "/api/" + c.apiVersion + path
|
||||||
if strings.EqualFold(method, http.MethodGet) {
|
if strings.EqualFold(method, http.MethodGet) {
|
||||||
qs := make(map[string]string)
|
qs := make(map[string]string)
|
||||||
if params != nil {
|
if params != nil {
|
||||||
|
44
migrations/1747389600_upgrade.go
Normal file
44
migrations/1747389600_upgrade.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package migrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pocketbase/pocketbase/core"
|
||||||
|
m "github.com/pocketbase/pocketbase/migrations"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
m.Register(func(app core.App) error {
|
||||||
|
// migrate data
|
||||||
|
{
|
||||||
|
accesses, err := app.FindAllRecords("access")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, access := range accesses {
|
||||||
|
changed := false
|
||||||
|
|
||||||
|
if access.GetString("provider") == "1panel" {
|
||||||
|
config := make(map[string]any)
|
||||||
|
if err := access.UnmarshalJSONField("config", &config); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
config["apiVersion"] = "v1"
|
||||||
|
access.Set("config", config)
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if changed {
|
||||||
|
err = app.Save(access)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}, func(app core.App) error {
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Form, type FormInstance, Input, Switch } from "antd";
|
import { Form, type FormInstance, Input, Select, Switch } from "antd";
|
||||||
import { createSchemaFieldRule } from "antd-zod";
|
import { createSchemaFieldRule } from "antd-zod";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
@ -18,6 +18,7 @@ export type AccessForm1PanelConfigProps = {
|
|||||||
const initFormModel = (): AccessForm1PanelConfigFieldValues => {
|
const initFormModel = (): AccessForm1PanelConfigFieldValues => {
|
||||||
return {
|
return {
|
||||||
apiUrl: "http://<your-host-addr>:20410/",
|
apiUrl: "http://<your-host-addr>:20410/",
|
||||||
|
apiVersion: "v1",
|
||||||
apiKey: "",
|
apiKey: "",
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -27,6 +28,7 @@ const AccessForm1PanelConfig = ({ form: formInst, formName, disabled, initialVal
|
|||||||
|
|
||||||
const formSchema = z.object({
|
const formSchema = z.object({
|
||||||
apiUrl: z.string().url(t("common.errmsg.url_invalid")),
|
apiUrl: z.string().url(t("common.errmsg.url_invalid")),
|
||||||
|
apiVersion: z.string().nonempty(t("access.form.1panel_api_version.placeholder")),
|
||||||
apiKey: z
|
apiKey: z
|
||||||
.string()
|
.string()
|
||||||
.min(1, t("access.form.1panel_api_key.placeholder"))
|
.min(1, t("access.form.1panel_api_key.placeholder"))
|
||||||
@ -53,6 +55,10 @@ const AccessForm1PanelConfig = ({ form: formInst, formName, disabled, initialVal
|
|||||||
<Input placeholder={t("access.form.1panel_api_url.placeholder")} />
|
<Input placeholder={t("access.form.1panel_api_url.placeholder")} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item name="apiVersion" label={t("access.form.1panel_api_version.label")} rules={[formRule]}>
|
||||||
|
<Select options={["v1", "v2"].map((s) => ({ label: s, value: s }))} placeholder={t("access.form.1panel_api_version.placeholder")} />
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="apiKey"
|
name="apiKey"
|
||||||
label={t("access.form.1panel_api_key.label")}
|
label={t("access.form.1panel_api_key.label")}
|
||||||
|
@ -69,6 +69,7 @@ export interface AccessModel extends BaseModel {
|
|||||||
// #region AccessConfig
|
// #region AccessConfig
|
||||||
export type AccessConfigFor1Panel = {
|
export type AccessConfigFor1Panel = {
|
||||||
apiUrl: string;
|
apiUrl: string;
|
||||||
|
apiVersion: string;
|
||||||
apiKey: string;
|
apiKey: string;
|
||||||
allowInsecureConnections?: boolean;
|
allowInsecureConnections?: boolean;
|
||||||
};
|
};
|
||||||
|
@ -36,6 +36,8 @@
|
|||||||
"access.form.notification_channel.placeholder": "Please select a notification channel",
|
"access.form.notification_channel.placeholder": "Please select a notification channel",
|
||||||
"access.form.1panel_api_url.label": "1Panel URL",
|
"access.form.1panel_api_url.label": "1Panel URL",
|
||||||
"access.form.1panel_api_url.placeholder": "Please enter 1Panel URL",
|
"access.form.1panel_api_url.placeholder": "Please enter 1Panel URL",
|
||||||
|
"access.form.1panel_api_version.label": "1Panel version",
|
||||||
|
"access.form.1panel_api_version.placeholder": "Please select 1Panel version",
|
||||||
"access.form.1panel_api_key.label": "1Panel API key",
|
"access.form.1panel_api_key.label": "1Panel API key",
|
||||||
"access.form.1panel_api_key.placeholder": "Please enter 1Panel API key",
|
"access.form.1panel_api_key.placeholder": "Please enter 1Panel API key",
|
||||||
"access.form.1panel_api_key.tooltip": "For more information, see <a href=\"https://docs.1panel.pro/dev_manual/api_manual/\" target=\"_blank\">https://docs.1panel.pro/dev_manual/api_manual/</a>",
|
"access.form.1panel_api_key.tooltip": "For more information, see <a href=\"https://docs.1panel.pro/dev_manual/api_manual/\" target=\"_blank\">https://docs.1panel.pro/dev_manual/api_manual/</a>",
|
||||||
@ -262,8 +264,8 @@
|
|||||||
"access.form.namesilo_api_key.label": "NameSilo API key",
|
"access.form.namesilo_api_key.label": "NameSilo API key",
|
||||||
"access.form.namesilo_api_key.placeholder": "Please enter NameSilo API key",
|
"access.form.namesilo_api_key.placeholder": "Please enter NameSilo API key",
|
||||||
"access.form.namesilo_api_key.tooltip": "For more information, see <a href=\"https://www.namesilo.com/support/v2/articles/account-options/api-manager\" target=\"_blank\">https://www.namesilo.com/support/v2/articles/account-options/api-manager</a>",
|
"access.form.namesilo_api_key.tooltip": "For more information, see <a href=\"https://www.namesilo.com/support/v2/articles/account-options/api-manager\" target=\"_blank\">https://www.namesilo.com/support/v2/articles/account-options/api-manager</a>",
|
||||||
"access.form.netlify_api_token.label": "netlify API token",
|
"access.form.netlify_api_token.label": "Netlify API token",
|
||||||
"access.form.netlify_api_token.placeholder": "Please enter netlify API token",
|
"access.form.netlify_api_token.placeholder": "Please enter Netlify API token",
|
||||||
"access.form.netlify_api_token.tooltip": "For more information, see <a href=\"https://docs.netlify.com/api/get-started/#authentication\" target=\"_blank\">https://docs.netlify.com/api/get-started/#authentication</a>",
|
"access.form.netlify_api_token.tooltip": "For more information, see <a href=\"https://docs.netlify.com/api/get-started/#authentication\" target=\"_blank\">https://docs.netlify.com/api/get-started/#authentication</a>",
|
||||||
"access.form.netcup_customer_number.label": "netcup customer number",
|
"access.form.netcup_customer_number.label": "netcup customer number",
|
||||||
"access.form.netcup_customer_number.placeholder": "Please enter netcup customer number",
|
"access.form.netcup_customer_number.placeholder": "Please enter netcup customer number",
|
||||||
|
@ -91,8 +91,8 @@
|
|||||||
"provider.namedotcom": "Name.com",
|
"provider.namedotcom": "Name.com",
|
||||||
"provider.namesilo": "NameSilo",
|
"provider.namesilo": "NameSilo",
|
||||||
"provider.netcup": "netcup",
|
"provider.netcup": "netcup",
|
||||||
"provider.netlify": "netlify",
|
"provider.netlify": "Netlify",
|
||||||
"provider.netlify.site": "netlify - Site",
|
"provider.netlify.site": "Netlify - Site",
|
||||||
"provider.ns1": "NS1 (IBM NS1 Connect)",
|
"provider.ns1": "NS1 (IBM NS1 Connect)",
|
||||||
"provider.porkbun": "Porkbun",
|
"provider.porkbun": "Porkbun",
|
||||||
"provider.powerdns": "PowerDNS",
|
"provider.powerdns": "PowerDNS",
|
||||||
|
@ -489,8 +489,8 @@
|
|||||||
"workflow_node.deploy.form.local_preset_scripts.option.ps_binding_iis.label": "PowerShell - Binding IIS",
|
"workflow_node.deploy.form.local_preset_scripts.option.ps_binding_iis.label": "PowerShell - Binding IIS",
|
||||||
"workflow_node.deploy.form.local_preset_scripts.option.ps_binding_netsh.label": "PowerShell - Binding netsh",
|
"workflow_node.deploy.form.local_preset_scripts.option.ps_binding_netsh.label": "PowerShell - Binding netsh",
|
||||||
"workflow_node.deploy.form.local_preset_scripts.option.ps_.label": "PowerShell - Binding RDP",
|
"workflow_node.deploy.form.local_preset_scripts.option.ps_.label": "PowerShell - Binding RDP",
|
||||||
"workflow_node.deploy.form.netlify_site_id.label": "netlify site ID",
|
"workflow_node.deploy.form.netlify_site_id.label": "Netlify site ID",
|
||||||
"workflow_node.deploy.form.netlify_site_id.placeholder": "Please enter netlify site ID",
|
"workflow_node.deploy.form.netlify_site_id.placeholder": "Please enter Netlify site ID",
|
||||||
"workflow_node.deploy.form.netlify_site_id.tooltip": "For more information, see <a href=\"https://docs.netlify.com/api/get-started/#get-site\" target=\"_blank\">https://docs.netlify.com/api/get-started/#get-site</a>",
|
"workflow_node.deploy.form.netlify_site_id.tooltip": "For more information, see <a href=\"https://docs.netlify.com/api/get-started/#get-site\" target=\"_blank\">https://docs.netlify.com/api/get-started/#get-site</a>",
|
||||||
"workflow_node.deploy.form.proxmoxve_node_name.label": "Proxmox VE cluster node name",
|
"workflow_node.deploy.form.proxmoxve_node_name.label": "Proxmox VE cluster node name",
|
||||||
"workflow_node.deploy.form.proxmoxve_node_name.placeholder": "Please enter Proxmox VE cluster node name",
|
"workflow_node.deploy.form.proxmoxve_node_name.placeholder": "Please enter Proxmox VE cluster node name",
|
||||||
|
@ -36,6 +36,8 @@
|
|||||||
"access.form.notification_channel.placeholder": "请选择通知渠道",
|
"access.form.notification_channel.placeholder": "请选择通知渠道",
|
||||||
"access.form.1panel_api_url.label": "1Panel URL",
|
"access.form.1panel_api_url.label": "1Panel URL",
|
||||||
"access.form.1panel_api_url.placeholder": "请输入 1Panel URL",
|
"access.form.1panel_api_url.placeholder": "请输入 1Panel URL",
|
||||||
|
"access.form.1panel_api_version.label": "1Panel 版本",
|
||||||
|
"access.form.1panel_api_version.placeholder": "请选择 1Panel 版本",
|
||||||
"access.form.1panel_api_key.label": "1Panel 接口密钥",
|
"access.form.1panel_api_key.label": "1Panel 接口密钥",
|
||||||
"access.form.1panel_api_key.placeholder": "请输入 1Panel 接口密钥",
|
"access.form.1panel_api_key.placeholder": "请输入 1Panel 接口密钥",
|
||||||
"access.form.1panel_api_key.tooltip": "这是什么?请参阅 <a href=\"https://1panel.cn/docs/dev_manual/api_manual/\" target=\"_blank\">https://1panel.cn/docs/dev_manual/api_manual/</a>",
|
"access.form.1panel_api_key.tooltip": "这是什么?请参阅 <a href=\"https://1panel.cn/docs/dev_manual/api_manual/\" target=\"_blank\">https://1panel.cn/docs/dev_manual/api_manual/</a>",
|
||||||
@ -256,8 +258,8 @@
|
|||||||
"access.form.namesilo_api_key.label": "NameSilo API Key",
|
"access.form.namesilo_api_key.label": "NameSilo API Key",
|
||||||
"access.form.namesilo_api_key.placeholder": "请输入 NameSilo API Key",
|
"access.form.namesilo_api_key.placeholder": "请输入 NameSilo API Key",
|
||||||
"access.form.namesilo_api_key.tooltip": "这是什么?请参阅 <a href=\"https://www.namesilo.com/support/v2/articles/account-options/api-manager\" target=\"_blank\">https://www.namesilo.com/support/v2/articles/account-options/api-manager</a>",
|
"access.form.namesilo_api_key.tooltip": "这是什么?请参阅 <a href=\"https://www.namesilo.com/support/v2/articles/account-options/api-manager\" target=\"_blank\">https://www.namesilo.com/support/v2/articles/account-options/api-manager</a>",
|
||||||
"access.form.netlify_api_token.label": "netlify API Token",
|
"access.form.netlify_api_token.label": "Netlify API Token",
|
||||||
"access.form.netlify_api_token.placeholder": "请输入 netlify API Token",
|
"access.form.netlify_api_token.placeholder": "请输入 Netlify API Token",
|
||||||
"access.form.netlify_api_token.tooltip": "这是什么?请参阅 <a href=\"https://docs.netlify.com/api/get-started/#authentication\" target=\"_blank\">https://docs.netlify.com/api/get-started/#authentication</a>",
|
"access.form.netlify_api_token.tooltip": "这是什么?请参阅 <a href=\"https://docs.netlify.com/api/get-started/#authentication\" target=\"_blank\">https://docs.netlify.com/api/get-started/#authentication</a>",
|
||||||
"access.form.netcup_customer_number.label": "netcup 客户编号",
|
"access.form.netcup_customer_number.label": "netcup 客户编号",
|
||||||
"access.form.netcup_customer_number.placeholder": "请输入 netcup 客户编号",
|
"access.form.netcup_customer_number.placeholder": "请输入 netcup 客户编号",
|
||||||
|
@ -91,8 +91,8 @@
|
|||||||
"provider.namedotcom": "Name.com",
|
"provider.namedotcom": "Name.com",
|
||||||
"provider.namesilo": "NameSilo",
|
"provider.namesilo": "NameSilo",
|
||||||
"provider.netcup": "netcup",
|
"provider.netcup": "netcup",
|
||||||
"provider.netlify": "netlify",
|
"provider.netlify": "Netlify",
|
||||||
"provider.netlify.site": "netlify - Site",
|
"provider.netlify.site": "Netlify - Site",
|
||||||
"provider.ns1": "NS1 (IBM NS1 Connect)",
|
"provider.ns1": "NS1 (IBM NS1 Connect)",
|
||||||
"provider.porkbun": "Porkbun",
|
"provider.porkbun": "Porkbun",
|
||||||
"provider.powerdns": "PowerDNS",
|
"provider.powerdns": "PowerDNS",
|
||||||
|
@ -488,7 +488,7 @@
|
|||||||
"workflow_node.deploy.form.local_preset_scripts.option.ps_binding_iis.label": "PowerShell - 导入并绑定到 IIS",
|
"workflow_node.deploy.form.local_preset_scripts.option.ps_binding_iis.label": "PowerShell - 导入并绑定到 IIS",
|
||||||
"workflow_node.deploy.form.local_preset_scripts.option.ps_binding_netsh.label": "PowerShell - 导入并绑定到 netsh",
|
"workflow_node.deploy.form.local_preset_scripts.option.ps_binding_netsh.label": "PowerShell - 导入并绑定到 netsh",
|
||||||
"workflow_node.deploy.form.local_preset_scripts.option.ps_binding_rdp.label": "PowerShell - 导入并绑定到 RDP",
|
"workflow_node.deploy.form.local_preset_scripts.option.ps_binding_rdp.label": "PowerShell - 导入并绑定到 RDP",
|
||||||
"workflow_node.deploy.form.netlify_site_id.label": "netlify 网站 ID",
|
"workflow_node.deploy.form.netlify_site_id.label": "Netlify 网站 ID",
|
||||||
"workflow_node.deploy.form.netlify_site_id.placeholder": "请输入 netlify 网站 ID",
|
"workflow_node.deploy.form.netlify_site_id.placeholder": "请输入 netlify 网站 ID",
|
||||||
"workflow_node.deploy.form.netlify_site_id.tooltip": "这是什么?请参阅 <a href=\"https://docs.netlify.com/api/get-started/#get-site\" target=\"_blank\">https://docs.netlify.com/api/get-started/#get-site</a>",
|
"workflow_node.deploy.form.netlify_site_id.tooltip": "这是什么?请参阅 <a href=\"https://docs.netlify.com/api/get-started/#get-site\" target=\"_blank\">https://docs.netlify.com/api/get-started/#get-site</a>",
|
||||||
"workflow_node.deploy.form.proxmoxve_node_name.label": "Proxmox VE 集群节点名称",
|
"workflow_node.deploy.form.proxmoxve_node_name.label": "Proxmox VE 集群节点名称",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user