diff --git a/internal/certdeploy/deployers/sp_baotapanelgo_site.go b/internal/certdeploy/deployers/sp_baotapanelgo_site.go index ebfaec89..4a5a3a2d 100644 --- a/internal/certdeploy/deployers/sp_baotapanelgo_site.go +++ b/internal/certdeploy/deployers/sp_baotapanelgo_site.go @@ -20,6 +20,7 @@ func init() { ServerUrl: credentials.ServerUrl, ApiKey: credentials.ApiKey, AllowInsecureConnections: credentials.AllowInsecureConnections, + SiteType: xmaps.GetString(options.ProviderExtendedConfig, "siteType"), SiteName: xmaps.GetString(options.ProviderExtendedConfig, "siteName"), }) return provider, err diff --git a/pkg/core/deployer/providers/baotapanelgo-site/baotapanelgo_site.go b/pkg/core/deployer/providers/baotapanelgo-site/baotapanelgo_site.go index 88ae4c70..684d14b2 100644 --- a/pkg/core/deployer/providers/baotapanelgo-site/baotapanelgo_site.go +++ b/pkg/core/deployer/providers/baotapanelgo-site/baotapanelgo_site.go @@ -24,6 +24,8 @@ type DeployerConfig struct { ApiKey string `json:"apiKey"` // 是否允许不安全的连接。 AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"` + // 网站类型。 + SiteType string `json:"siteType"` // 网站名称。 SiteName string `json:"siteName,omitempty"` } @@ -36,6 +38,8 @@ type Deployer struct { var _ deployer.Provider = (*Deployer)(nil) +var projectTypesInIIS = []string{"php", "asp", "aspx"} + func NewDeployer(config *DeployerConfig) (*Deployer, error) { if config == nil { return nil, errors.New("the configuration of the deployer provider is nil") @@ -66,7 +70,7 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*dep return nil, errors.New("config `siteName` is required") } - // 设置站点 SSL 证书 + // 获取面板配置 panelGetConfigReq := &btsdk.PanelGetConfigRequest{} panelGetConfigResp, err := d.sdkClient.PanelGetConfig(panelGetConfigReq) d.logger.Debug("sdk request 'bt.PanelGetConfig'", slog.Any("request", panelGetConfigReq), slog.Any("response", panelGetConfigResp)) @@ -74,13 +78,17 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*dep return nil, fmt.Errorf("failed to execute sdk request 'bt.PanelGetConfig': %w", err) } - // 获取网站 ID - siteId, err := d.findSiteIdByName(ctx, d.config.SiteName) + // 获取网站 + siteData, err := d.findSiteIdByName(ctx, d.config.SiteType, d.config.SiteName) if err != nil { return nil, err } - if panelGetConfigResp.Site != nil && strings.EqualFold(panelGetConfigResp.Site.WebServer, "iis") { + // 根据网站部署证书 + // 服务器为 IIS、且网站类型为 PHP/.NET/Node/Proxy,需上传 PFX 格式证书 + pfxRequried := lo.Contains(projectTypesInIIS, siteData.ProjectType) && + panelGetConfigResp.Site != nil && strings.EqualFold(panelGetConfigResp.Site.WebServer, "iis") + if pfxRequried { // 转换证书格式 certPFXPassword := "certimate" certPFX, err := xcert.TransformCertificateFromPEMToPFX(certPEM, privkeyPEM, certPFXPassword) @@ -109,7 +117,7 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*dep // 服务器为 IIS,设置网站 SSL siteSetSitePFXSSLReq := &btsdk.SiteSetSitePFXSSLRequest{ - SiteId: lo.ToPtr(siteId), + SiteId: lo.ToPtr(siteData.Id), PFX: lo.ToPtr(fmt.Sprintf("%s/%s", certPFXPath, certPFXFileName)), Password: lo.ToPtr(certPFXPassword), } @@ -121,7 +129,7 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*dep } else { // 服务器非 IIS,设置网站 SSL siteSetSiteSSLReq := &btsdk.SiteSetSiteSSLRequest{ - SiteId: lo.ToPtr(siteId), + SiteId: lo.ToPtr(siteData.Id), Status: lo.ToPtr(true), Key: lo.ToPtr(privkeyPEM), Cert: lo.ToPtr(certPEM), @@ -136,43 +144,80 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*dep return &deployer.DeployResult{}, nil } -func (d *Deployer) findSiteIdByName(ctx context.Context, siteName string) (int32, error) { - // 查询网站列表 - datalistGetDataListPage := 1 - datalistGetDataListLimit := 10 - for { - select { - case <-ctx.Done(): - return 0, ctx.Err() - default: - } - - datalistGetDataListReq := &btsdk.DatalistGetDataListRequest{ - Table: lo.ToPtr("sites"), - SearchString: lo.ToPtr(d.config.SiteName), - Page: lo.ToPtr(int32(datalistGetDataListPage)), - Limit: lo.ToPtr(int32(datalistGetDataListLimit)), - } - datalistGetDataListResp, err := d.sdkClient.DatalistGetDataList(datalistGetDataListReq) - d.logger.Debug("sdk request 'bt.DatalistGetDataList'", slog.Any("request", datalistGetDataListReq), slog.Any("response", datalistGetDataListResp)) - if err != nil { - return 0, fmt.Errorf("failed to execute sdk request 'bt.DatalistGetDataList': %w", err) - } - - for _, siteItem := range datalistGetDataListResp.Data { - if strings.EqualFold(siteItem.Name, d.config.SiteName) { - return siteItem.Id, nil +func (d *Deployer) findSiteIdByName(ctx context.Context, siteType string, siteName string) (*btsdk.SiteData, error) { + if siteType == "" || lo.Contains(projectTypesInIIS, siteType) { + // 查询网站列表 + datalistGetDataListPage := 1 + datalistGetDataListLimit := 10 + for { + select { + case <-ctx.Done(): + return nil, ctx.Err() + default: } - } - if len(datalistGetDataListResp.Data) < datalistGetDataListLimit { - break - } + datalistGetDataListReq := &btsdk.DatalistGetDataListRequest{ + Table: lo.ToPtr("sites"), + SearchString: lo.ToPtr(siteName), + Page: lo.ToPtr(int32(datalistGetDataListPage)), + Limit: lo.ToPtr(int32(datalistGetDataListLimit)), + } + datalistGetDataListResp, err := d.sdkClient.DatalistGetDataList(datalistGetDataListReq) + d.logger.Debug("sdk request 'bt.DatalistGetDataList'", slog.Any("request", datalistGetDataListReq), slog.Any("response", datalistGetDataListResp)) + if err != nil { + return nil, fmt.Errorf("failed to execute sdk request 'bt.DatalistGetDataList': %w", err) + } - datalistGetDataListPage++ + for _, siteItem := range datalistGetDataListResp.Data { + if strings.EqualFold(siteItem.Name, siteName) { + return siteItem, nil + } + } + + if len(datalistGetDataListResp.Data) < datalistGetDataListLimit { + break + } + + datalistGetDataListPage++ + } + } else { + // 查询网站列表 + siteGetProjectListPage := 1 + siteGetProjectListLimit := 10 + for { + select { + case <-ctx.Done(): + return nil, ctx.Err() + default: + } + + siteGetProjectListReq := &btsdk.SiteGetProjectListRequest{ + SearchType: lo.ToPtr(siteType), + SearchString: lo.ToPtr(siteName), + Page: lo.ToPtr(int32(siteGetProjectListPage)), + Limit: lo.ToPtr(int32(siteGetProjectListLimit)), + } + siteGetProjectListResp, err := d.sdkClient.SiteGetProjectList(siteGetProjectListReq) + d.logger.Debug("sdk request 'bt.SiteGetProjectList'", slog.Any("request", siteGetProjectListReq), slog.Any("response", siteGetProjectListResp)) + if err != nil { + return nil, fmt.Errorf("failed to execute sdk request 'bt.SiteGetProjectList': %w", err) + } + + for _, siteItem := range siteGetProjectListResp.Data { + if strings.EqualFold(siteItem.Name, siteName) { + return siteItem, nil + } + } + + if len(siteGetProjectListResp.Data) < siteGetProjectListLimit { + break + } + + siteGetProjectListPage++ + } } - return 0, fmt.Errorf("could not find site '%s'", siteName) + return nil, fmt.Errorf("could not find site '%s'", siteName) } func createSDKClient(serverUrl, apiKey string, skipTlsVerify bool) (*btsdk.Client, error) { diff --git a/pkg/core/deployer/providers/baotapanelgo-site/baotapanelgo_site_test.go b/pkg/core/deployer/providers/baotapanelgo-site/baotapanelgo_site_test.go index b6a85c2d..0d2223a9 100644 --- a/pkg/core/deployer/providers/baotapanelgo-site/baotapanelgo_site_test.go +++ b/pkg/core/deployer/providers/baotapanelgo-site/baotapanelgo_site_test.go @@ -16,6 +16,7 @@ var ( fInputKeyPath string fServerUrl string fApiKey string + fSiteType string fSiteName string ) @@ -26,17 +27,19 @@ func init() { flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "") flag.StringVar(&fServerUrl, argsPrefix+"SERVERURL", "", "") flag.StringVar(&fApiKey, argsPrefix+"APIKEY", "", "") + flag.StringVar(&fSiteType, argsPrefix+"SITETYPE", "", "") flag.StringVar(&fSiteName, argsPrefix+"SITENAME", "", "") } /* Shell command to run this test: - go test -v ./baotapanel_site_test.go -args \ + go test -v ./baotapanelgo_site_test.go -args \ --BAOTAPANELGOSITE_INPUTCERTPATH="/path/to/your-input-cert.pem" \ --BAOTAPANELGOSITE_INPUTKEYPATH="/path/to/your-input-key.pem" \ --BAOTAPANELGOSITE_SERVERURL="http://127.0.0.1:8888" \ --BAOTAPANELGOSITE_APIKEY="your-api-key" \ + --BAOTAPANELGOSITE_SITETYPE="your-site-type" \ --BAOTAPANELGOSITE_SITENAME="your-site-name" */ func TestDeploy(t *testing.T) { @@ -49,6 +52,7 @@ func TestDeploy(t *testing.T) { fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath), fmt.Sprintf("SERVERURL: %v", fServerUrl), fmt.Sprintf("APIKEY: %v", fApiKey), + fmt.Sprintf("SITETYPE: %v", fSiteType), fmt.Sprintf("SITENAME: %v", fSiteName), }, "\n")) @@ -56,6 +60,7 @@ func TestDeploy(t *testing.T) { ServerUrl: fServerUrl, ApiKey: fApiKey, AllowInsecureConnections: true, + SiteType: fSiteType, SiteName: fSiteName, }) if err != nil { diff --git a/pkg/sdk3rd/btpanelgo/api_site_get_project_list.go b/pkg/sdk3rd/btpanelgo/api_site_get_project_list.go new file mode 100644 index 00000000..4000e025 --- /dev/null +++ b/pkg/sdk3rd/btpanelgo/api_site_get_project_list.go @@ -0,0 +1,40 @@ +package btpanel + +import ( + "context" + "net/http" +) + +type SiteGetProjectListRequest struct { + SearchType *string `json:"search_type,omitempty"` + SearchString *string `json:"search,omitempty"` + Page *int32 `json:"p,omitempty"` + Limit *int32 `json:"limit,omitempty"` + Order *string `json:"order,omitempty"` +} + +type SiteGetProjectListResponse struct { + apiResponseBase + Data []*SiteData `json:"data,omitempty"` + Page *PageData `json:"page,omitempty"` +} + +func (c *Client) SiteGetProjectList(req *SiteGetProjectListRequest) (*SiteGetProjectListResponse, error) { + return c.SiteGetProjectListWithContext(context.Background(), req) +} + +func (c *Client) SiteGetProjectListWithContext(ctx context.Context, req *SiteGetProjectListRequest) (*SiteGetProjectListResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/site/get_project_list", req, false) + if err != nil { + return nil, err + } else { + httpreq.SetContext(ctx) + } + + result := &SiteGetProjectListResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/pkg/sdk3rd/btpanelgo/types.go b/pkg/sdk3rd/btpanelgo/types.go index 4d88382d..b389892a 100644 --- a/pkg/sdk3rd/btpanelgo/types.go +++ b/pkg/sdk3rd/btpanelgo/types.go @@ -4,10 +4,6 @@ import ( "encoding/json" ) -type apiRequestWithBlob interface { - GetBlob() []byte -} - type apiResponse interface { GetStatus() json.RawMessage GetMessage() *string @@ -28,11 +24,16 @@ func (r *apiResponseBase) GetMessage() *string { } type SiteData struct { - Id int32 `json:"id"` - Name string `json:"name"` - ProjectType string `json:"project_type"` - ProjectConfig string `json:"project_config"` - AddTime string `json:"addTime"` + Id int32 `json:"id"` + ProjectType string `json:"project_type"` + Name string `json:"name"` + Note string `json:"ps"` + Status string `json:"status"` + SSLInfo []*struct { + Name string `json:"name"` + Status bool `json:"status"` + } `json:"ssl_info"` + AddTime string `json:"addtime"` } type PageData struct { diff --git a/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderBaotaPanelGoConsole.tsx b/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderBaotaPanelGoConsole.tsx index 48e0cce5..16e4a81b 100644 --- a/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderBaotaPanelGoConsole.tsx +++ b/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderBaotaPanelGoConsole.tsx @@ -1,21 +1,7 @@ import { getI18n } from "react-i18next"; -// import { getI18n, useTranslation } from "react-i18next"; -// import { Form, Switch } from "antd"; -// import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -// import { useFormNestedFieldsContext } from "./_context"; - const BizDeployNodeConfigFieldsProviderBaotaPanelConsoleGo = () => { - // const { i18n, t } = useTranslation(); - - // const { parentNamePath } = useFormNestedFieldsContext(); - // const formSchema = z.object({ - // [parentNamePath]: getSchema({ i18n }), - // }); - // const formRule = createSchemaFieldRule(formSchema); - // const initialValues = getInitialValues(); - return <>>; }; diff --git a/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderBaotaPanelGoSite.tsx b/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderBaotaPanelGoSite.tsx index c6069b64..a8b81202 100644 --- a/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderBaotaPanelGoSite.tsx +++ b/ui/src/components/workflow/designer/forms/BizDeployNodeConfigFieldsProviderBaotaPanelGoSite.tsx @@ -1,5 +1,5 @@ import { getI18n, useTranslation } from "react-i18next"; -import { Form, Input } from "antd"; +import { Form, Input, Select } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; @@ -17,6 +17,21 @@ const BizDeployNodeConfigFieldsProviderBaotaPanelGoSite = () => { return ( <> +