mirror of
https://github.com/woodchen-ink/certimate.git
synced 2025-07-18 09:21:56 +08:00
feat: deprecate old notification module and introduce new notifier module
This commit is contained in:
parent
2d17501072
commit
7478dd7f47
@ -8,6 +8,7 @@ type NotifyChannelType string
|
||||
注意:如果追加新的常量值,请保持以 ASCII 排序。
|
||||
NOTICE: If you add new constant, please keep ASCII order.
|
||||
*/
|
||||
// Deprecated: v0.4.x 将废弃
|
||||
const (
|
||||
NotifyChannelTypeBark = NotifyChannelType("bark")
|
||||
NotifyChannelTypeDingTalk = NotifyChannelType("dingtalk")
|
||||
|
@ -19,6 +19,7 @@ const (
|
||||
AccessProviderTypeBaishan = AccessProviderType("baishan")
|
||||
AccessProviderTypeBaotaPanel = AccessProviderType("baotapanel")
|
||||
AccessProviderTypeBytePlus = AccessProviderType("byteplus")
|
||||
AccessProviderTypeBunny = AccessProviderType("bunny")
|
||||
AccessProviderTypeBuypass = AccessProviderType("buypass")
|
||||
AccessProviderTypeCacheFly = AccessProviderType("cachefly")
|
||||
AccessProviderTypeCdnfly = AccessProviderType("cdnfly")
|
||||
@ -71,18 +72,18 @@ type ApplyCAProviderType string
|
||||
|
||||
/*
|
||||
申请证书 CA 提供商常量值。
|
||||
始终等于授权提供商类型。
|
||||
短横线前的部分始终等于授权提供商类型。
|
||||
|
||||
注意:如果追加新的常量值,请保持以 ASCII 排序。
|
||||
NOTICE: If you add new constant, please keep ASCII order.
|
||||
*/
|
||||
const (
|
||||
ApplyCAProviderTypeBuypass = ApplyCAProviderType(string(AccessProviderTypeBuypass))
|
||||
ApplyCAProviderTypeGoogleTrustServices = ApplyCAProviderType(string(AccessProviderTypeGoogleTrustServices))
|
||||
ApplyCAProviderTypeLetsEncrypt = ApplyCAProviderType(string(AccessProviderTypeLetsEncrypt))
|
||||
ApplyCAProviderTypeLetsEncryptStaging = ApplyCAProviderType(string(AccessProviderTypeLetsEncryptStaging))
|
||||
ApplyCAProviderTypeSSLCom = ApplyCAProviderType(string(AccessProviderTypeSSLCOM))
|
||||
ApplyCAProviderTypeZeroSSL = ApplyCAProviderType(string(AccessProviderTypeZeroSSL))
|
||||
ApplyCAProviderTypeBuypass = ApplyCAProviderType(AccessProviderTypeBuypass)
|
||||
ApplyCAProviderTypeGoogleTrustServices = ApplyCAProviderType(AccessProviderTypeGoogleTrustServices)
|
||||
ApplyCAProviderTypeLetsEncrypt = ApplyCAProviderType(AccessProviderTypeLetsEncrypt)
|
||||
ApplyCAProviderTypeLetsEncryptStaging = ApplyCAProviderType(AccessProviderTypeLetsEncryptStaging)
|
||||
ApplyCAProviderTypeSSLCom = ApplyCAProviderType(AccessProviderTypeSSLCOM)
|
||||
ApplyCAProviderTypeZeroSSL = ApplyCAProviderType(AccessProviderTypeZeroSSL)
|
||||
)
|
||||
|
||||
type ApplyDNSProviderType string
|
||||
@ -95,43 +96,43 @@ type ApplyDNSProviderType string
|
||||
NOTICE: If you add new constant, please keep ASCII order.
|
||||
*/
|
||||
const (
|
||||
ApplyDNSProviderTypeACMEHttpReq = ApplyDNSProviderType("acmehttpreq")
|
||||
ApplyDNSProviderTypeAliyun = ApplyDNSProviderType("aliyun") // 兼容旧值,等同于 [ApplyDNSProviderTypeAliyunDNS]
|
||||
ApplyDNSProviderTypeAliyunDNS = ApplyDNSProviderType("aliyun-dns")
|
||||
ApplyDNSProviderTypeAWS = ApplyDNSProviderType("aws") // 兼容旧值,等同于 [ApplyDNSProviderTypeAWSRoute53]
|
||||
ApplyDNSProviderTypeAWSRoute53 = ApplyDNSProviderType("aws-route53")
|
||||
ApplyDNSProviderTypeAzure = ApplyDNSProviderType("azure") // 兼容旧值,等同于 [ApplyDNSProviderTypeAzure]
|
||||
ApplyDNSProviderTypeAzureDNS = ApplyDNSProviderType("azure-dns")
|
||||
ApplyDNSProviderTypeBaiduCloud = ApplyDNSProviderType("baiducloud") // 兼容旧值,等同于 [ApplyDNSProviderTypeBaiduCloudDNS]
|
||||
ApplyDNSProviderTypeBaiduCloudDNS = ApplyDNSProviderType("baiducloud-dns")
|
||||
ApplyDNSProviderTypeBunny = ApplyDNSProviderType("bunny")
|
||||
ApplyDNSProviderTypeCloudflare = ApplyDNSProviderType("cloudflare")
|
||||
ApplyDNSProviderTypeClouDNS = ApplyDNSProviderType("cloudns")
|
||||
ApplyDNSProviderTypeCMCCCloud = ApplyDNSProviderType("cmcccloud")
|
||||
ApplyDNSProviderTypeDeSEC = ApplyDNSProviderType("desec")
|
||||
ApplyDNSProviderTypeDNSLA = ApplyDNSProviderType("dnsla")
|
||||
ApplyDNSProviderTypeDynv6 = ApplyDNSProviderType("dynv6")
|
||||
ApplyDNSProviderTypeGcore = ApplyDNSProviderType("gcore")
|
||||
ApplyDNSProviderTypeGname = ApplyDNSProviderType("gname")
|
||||
ApplyDNSProviderTypeGoDaddy = ApplyDNSProviderType("godaddy")
|
||||
ApplyDNSProviderTypeHuaweiCloud = ApplyDNSProviderType("huaweicloud") // 兼容旧值,等同于 [ApplyDNSProviderTypeHuaweiCloudDNS]
|
||||
ApplyDNSProviderTypeHuaweiCloudDNS = ApplyDNSProviderType("huaweicloud-dns")
|
||||
ApplyDNSProviderTypeJDCloud = ApplyDNSProviderType("jdcloud") // 兼容旧值,等同于 [ApplyDNSProviderTypeJDCloudDNS]
|
||||
ApplyDNSProviderTypeJDCloudDNS = ApplyDNSProviderType("jdcloud-dns")
|
||||
ApplyDNSProviderTypeNamecheap = ApplyDNSProviderType("namecheap")
|
||||
ApplyDNSProviderTypeNameDotCom = ApplyDNSProviderType("namedotcom")
|
||||
ApplyDNSProviderTypeNameSilo = ApplyDNSProviderType("namesilo")
|
||||
ApplyDNSProviderTypeNS1 = ApplyDNSProviderType("ns1")
|
||||
ApplyDNSProviderTypePorkbun = ApplyDNSProviderType("porkbun")
|
||||
ApplyDNSProviderTypePowerDNS = ApplyDNSProviderType("powerdns")
|
||||
ApplyDNSProviderTypeRainYun = ApplyDNSProviderType("rainyun")
|
||||
ApplyDNSProviderTypeTencentCloud = ApplyDNSProviderType("tencentcloud") // 兼容旧值,等同于 [ApplyDNSProviderTypeTencentCloudDNS]
|
||||
ApplyDNSProviderTypeTencentCloudDNS = ApplyDNSProviderType("tencentcloud-dns")
|
||||
ApplyDNSProviderTypeTencentCloudEO = ApplyDNSProviderType("tencentcloud-eo")
|
||||
ApplyDNSProviderTypeVercel = ApplyDNSProviderType("vercel")
|
||||
ApplyDNSProviderTypeVolcEngine = ApplyDNSProviderType("volcengine") // 兼容旧值,等同于 [ApplyDNSProviderTypeVolcEngineDNS]
|
||||
ApplyDNSProviderTypeVolcEngineDNS = ApplyDNSProviderType("volcengine-dns")
|
||||
ApplyDNSProviderTypeWestcn = ApplyDNSProviderType("westcn")
|
||||
ApplyDNSProviderTypeACMEHttpReq = ApplyDNSProviderType(AccessProviderTypeACMEHttpReq)
|
||||
ApplyDNSProviderTypeAliyun = ApplyDNSProviderType(AccessProviderTypeAliyun) // 兼容旧值,等同于 [ApplyDNSProviderTypeAliyunDNS]
|
||||
ApplyDNSProviderTypeAliyunDNS = ApplyDNSProviderType(AccessProviderTypeAliyun + "-dns")
|
||||
ApplyDNSProviderTypeAWS = ApplyDNSProviderType(AccessProviderTypeAWS) // 兼容旧值,等同于 [ApplyDNSProviderTypeAWSRoute53]
|
||||
ApplyDNSProviderTypeAWSRoute53 = ApplyDNSProviderType(AccessProviderTypeAWS + "-route53")
|
||||
ApplyDNSProviderTypeAzure = ApplyDNSProviderType(AccessProviderTypeAzure) // 兼容旧值,等同于 [ApplyDNSProviderTypeAzure]
|
||||
ApplyDNSProviderTypeAzureDNS = ApplyDNSProviderType(AccessProviderTypeAzure + "-dns")
|
||||
ApplyDNSProviderTypeBaiduCloud = ApplyDNSProviderType(AccessProviderTypeBaiduCloud) // 兼容旧值,等同于 [ApplyDNSProviderTypeBaiduCloudDNS]
|
||||
ApplyDNSProviderTypeBaiduCloudDNS = ApplyDNSProviderType(AccessProviderTypeBaiduCloud + "-dns")
|
||||
ApplyDNSProviderTypeBunny = ApplyDNSProviderType(AccessProviderTypeBunny)
|
||||
ApplyDNSProviderTypeCloudflare = ApplyDNSProviderType(AccessProviderTypeCloudflare)
|
||||
ApplyDNSProviderTypeClouDNS = ApplyDNSProviderType(AccessProviderTypeClouDNS)
|
||||
ApplyDNSProviderTypeCMCCCloud = ApplyDNSProviderType(AccessProviderTypeCMCCCloud)
|
||||
ApplyDNSProviderTypeDeSEC = ApplyDNSProviderType(AccessProviderTypeDeSEC)
|
||||
ApplyDNSProviderTypeDNSLA = ApplyDNSProviderType(AccessProviderTypeDNSLA)
|
||||
ApplyDNSProviderTypeDynv6 = ApplyDNSProviderType(AccessProviderTypeDynv6)
|
||||
ApplyDNSProviderTypeGcore = ApplyDNSProviderType(AccessProviderTypeGcore)
|
||||
ApplyDNSProviderTypeGname = ApplyDNSProviderType(AccessProviderTypeGname)
|
||||
ApplyDNSProviderTypeGoDaddy = ApplyDNSProviderType(AccessProviderTypeGoDaddy)
|
||||
ApplyDNSProviderTypeHuaweiCloud = ApplyDNSProviderType(AccessProviderTypeHuaweiCloud) // 兼容旧值,等同于 [ApplyDNSProviderTypeHuaweiCloudDNS]
|
||||
ApplyDNSProviderTypeHuaweiCloudDNS = ApplyDNSProviderType(AccessProviderTypeHuaweiCloud + "-dns")
|
||||
ApplyDNSProviderTypeJDCloud = ApplyDNSProviderType(AccessProviderTypeJDCloud) // 兼容旧值,等同于 [ApplyDNSProviderTypeJDCloudDNS]
|
||||
ApplyDNSProviderTypeJDCloudDNS = ApplyDNSProviderType(AccessProviderTypeJDCloud + "-dns")
|
||||
ApplyDNSProviderTypeNamecheap = ApplyDNSProviderType(AccessProviderTypeNamecheap)
|
||||
ApplyDNSProviderTypeNameDotCom = ApplyDNSProviderType(AccessProviderTypeNameDotCom)
|
||||
ApplyDNSProviderTypeNameSilo = ApplyDNSProviderType(AccessProviderTypeNameSilo)
|
||||
ApplyDNSProviderTypeNS1 = ApplyDNSProviderType(AccessProviderTypeNS1)
|
||||
ApplyDNSProviderTypePorkbun = ApplyDNSProviderType(AccessProviderTypePorkbun)
|
||||
ApplyDNSProviderTypePowerDNS = ApplyDNSProviderType(AccessProviderTypePowerDNS)
|
||||
ApplyDNSProviderTypeRainYun = ApplyDNSProviderType(AccessProviderTypeRainYun)
|
||||
ApplyDNSProviderTypeTencentCloud = ApplyDNSProviderType(AccessProviderTypeTencentCloud) // 兼容旧值,等同于 [ApplyDNSProviderTypeTencentCloudDNS]
|
||||
ApplyDNSProviderTypeTencentCloudDNS = ApplyDNSProviderType(AccessProviderTypeTencentCloud + "-dns")
|
||||
ApplyDNSProviderTypeTencentCloudEO = ApplyDNSProviderType(AccessProviderTypeTencentCloud + "-eo")
|
||||
ApplyDNSProviderTypeVercel = ApplyDNSProviderType(AccessProviderTypeVercel)
|
||||
ApplyDNSProviderTypeVolcEngine = ApplyDNSProviderType(AccessProviderTypeVolcEngine) // 兼容旧值,等同于 [ApplyDNSProviderTypeVolcEngineDNS]
|
||||
ApplyDNSProviderTypeVolcEngineDNS = ApplyDNSProviderType(AccessProviderTypeVolcEngine + "-dns")
|
||||
ApplyDNSProviderTypeWestcn = ApplyDNSProviderType(AccessProviderTypeWestcn)
|
||||
)
|
||||
|
||||
type DeployProviderType string
|
||||
@ -144,78 +145,91 @@ type DeployProviderType string
|
||||
NOTICE: If you add new constant, please keep ASCII order.
|
||||
*/
|
||||
const (
|
||||
DeployProviderType1PanelConsole = DeployProviderType("1panel-console")
|
||||
DeployProviderType1PanelSite = DeployProviderType("1panel-site")
|
||||
DeployProviderTypeAliyunALB = DeployProviderType("aliyun-alb")
|
||||
DeployProviderTypeAliyunAPIGW = DeployProviderType("aliyun-apigw")
|
||||
DeployProviderTypeAliyunCAS = DeployProviderType("aliyun-cas")
|
||||
DeployProviderTypeAliyunCASDeploy = DeployProviderType("aliyun-casdeploy")
|
||||
DeployProviderTypeAliyunCDN = DeployProviderType("aliyun-cdn")
|
||||
DeployProviderTypeAliyunCLB = DeployProviderType("aliyun-clb")
|
||||
DeployProviderTypeAliyunDCDN = DeployProviderType("aliyun-dcdn")
|
||||
DeployProviderTypeAliyunESA = DeployProviderType("aliyun-esa")
|
||||
DeployProviderTypeAliyunFC = DeployProviderType("aliyun-fc")
|
||||
DeployProviderTypeAliyunLive = DeployProviderType("aliyun-live")
|
||||
DeployProviderTypeAliyunNLB = DeployProviderType("aliyun-nlb")
|
||||
DeployProviderTypeAliyunOSS = DeployProviderType("aliyun-oss")
|
||||
DeployProviderTypeAliyunVOD = DeployProviderType("aliyun-vod")
|
||||
DeployProviderTypeAliyunWAF = DeployProviderType("aliyun-waf")
|
||||
DeployProviderTypeAWSACM = DeployProviderType("aws-acm")
|
||||
DeployProviderTypeAWSCloudFront = DeployProviderType("aws-cloudfront")
|
||||
DeployProviderTypeAzureKeyVault = DeployProviderType("azure-keyvault")
|
||||
DeployProviderTypeBaiduCloudAppBLB = DeployProviderType("baiducloud-appblb")
|
||||
DeployProviderTypeBaiduCloudBLB = DeployProviderType("baiducloud-blb")
|
||||
DeployProviderTypeBaiduCloudCDN = DeployProviderType("baiducloud-cdn")
|
||||
DeployProviderTypeBaiduCloudCert = DeployProviderType("baiducloud-cert")
|
||||
DeployProviderTypeBaishanCDN = DeployProviderType("baishan-cdn")
|
||||
DeployProviderTypeBaotaPanelConsole = DeployProviderType("baotapanel-console")
|
||||
DeployProviderTypeBaotaPanelSite = DeployProviderType("baotapanel-site")
|
||||
DeployProviderTypeBunnyCDN = DeployProviderType("bunny-cdn")
|
||||
DeployProviderTypeBytePlusCDN = DeployProviderType("byteplus-cdn")
|
||||
DeployProviderTypeCacheFly = DeployProviderType("cachefly")
|
||||
DeployProviderTypeCdnfly = DeployProviderType("cdnfly")
|
||||
DeployProviderTypeDogeCloudCDN = DeployProviderType("dogecloud-cdn")
|
||||
DeployProviderTypeEdgioApplications = DeployProviderType("edgio-applications")
|
||||
DeployProviderTypeGcoreCDN = DeployProviderType("gcore-cdn")
|
||||
DeployProviderTypeHuaweiCloudCDN = DeployProviderType("huaweicloud-cdn")
|
||||
DeployProviderTypeHuaweiCloudELB = DeployProviderType("huaweicloud-elb")
|
||||
DeployProviderTypeHuaweiCloudSCM = DeployProviderType("huaweicloud-scm")
|
||||
DeployProviderTypeHuaweiCloudWAF = DeployProviderType("huaweicloud-waf")
|
||||
DeployProviderTypeJDCloudALB = DeployProviderType("jdcloud-alb")
|
||||
DeployProviderTypeJDCloudCDN = DeployProviderType("jdcloud-cdn")
|
||||
DeployProviderTypeJDCloudLive = DeployProviderType("jdcloud-live")
|
||||
DeployProviderTypeJDCloudVOD = DeployProviderType("jdcloud-vod")
|
||||
DeployProviderTypeKubernetesSecret = DeployProviderType("k8s-secret")
|
||||
DeployProviderTypeLocal = DeployProviderType("local")
|
||||
DeployProviderTypeQiniuCDN = DeployProviderType("qiniu-cdn")
|
||||
DeployProviderTypeQiniuKodo = DeployProviderType("qiniu-kodo")
|
||||
DeployProviderTypeQiniuPili = DeployProviderType("qiniu-pili")
|
||||
DeployProviderTypeRainYunRCDN = DeployProviderType("rainyun-rcdn")
|
||||
DeployProviderTypeSafeLine = DeployProviderType("safeline")
|
||||
DeployProviderTypeSSH = DeployProviderType("ssh")
|
||||
DeployProviderTypeTencentCloudCDN = DeployProviderType("tencentcloud-cdn")
|
||||
DeployProviderTypeTencentCloudCLB = DeployProviderType("tencentcloud-clb")
|
||||
DeployProviderTypeTencentCloudCOS = DeployProviderType("tencentcloud-cos")
|
||||
DeployProviderTypeTencentCloudCSS = DeployProviderType("tencentcloud-css")
|
||||
DeployProviderTypeTencentCloudECDN = DeployProviderType("tencentcloud-ecdn")
|
||||
DeployProviderTypeTencentCloudEO = DeployProviderType("tencentcloud-eo")
|
||||
DeployProviderTypeTencentCloudSCF = DeployProviderType("tencentcloud-scf")
|
||||
DeployProviderTypeTencentCloudSSL = DeployProviderType("tencentcloud-ssl")
|
||||
DeployProviderTypeTencentCloudSSLDeploy = DeployProviderType("tencentcloud-ssldeploy")
|
||||
DeployProviderTypeTencentCloudVOD = DeployProviderType("tencentcloud-vod")
|
||||
DeployProviderTypeTencentCloudWAF = DeployProviderType("tencentcloud-waf")
|
||||
DeployProviderTypeUCloudUCDN = DeployProviderType("ucloud-ucdn")
|
||||
DeployProviderTypeUCloudUS3 = DeployProviderType("ucloud-us3")
|
||||
DeployProviderTypeUpyunCDN = DeployProviderType("upyun-cdn")
|
||||
DeployProviderTypeUpyunFile = DeployProviderType("upyun-file")
|
||||
DeployProviderTypeVolcEngineALB = DeployProviderType("volcengine-alb")
|
||||
DeployProviderTypeVolcEngineCDN = DeployProviderType("volcengine-cdn")
|
||||
DeployProviderTypeVolcEngineCertCenter = DeployProviderType("volcengine-certcenter")
|
||||
DeployProviderTypeVolcEngineCLB = DeployProviderType("volcengine-clb")
|
||||
DeployProviderTypeVolcEngineDCDN = DeployProviderType("volcengine-dcdn")
|
||||
DeployProviderTypeVolcEngineImageX = DeployProviderType("volcengine-imagex")
|
||||
DeployProviderTypeVolcEngineLive = DeployProviderType("volcengine-live")
|
||||
DeployProviderTypeVolcEngineTOS = DeployProviderType("volcengine-tos")
|
||||
DeployProviderTypeWangsuCDNPro = DeployProviderType("wangsu-cdnpro")
|
||||
DeployProviderTypeWebhook = DeployProviderType("webhook")
|
||||
DeployProviderType1PanelConsole = DeployProviderType(AccessProviderType1Panel + "-console")
|
||||
DeployProviderType1PanelSite = DeployProviderType(AccessProviderType1Panel + "-site")
|
||||
DeployProviderTypeAliyunALB = DeployProviderType(AccessProviderTypeAliyun + "-alb")
|
||||
DeployProviderTypeAliyunAPIGW = DeployProviderType(AccessProviderTypeAliyun + "-apigw")
|
||||
DeployProviderTypeAliyunCAS = DeployProviderType(AccessProviderTypeAliyun + "-cas")
|
||||
DeployProviderTypeAliyunCASDeploy = DeployProviderType(AccessProviderTypeAliyun + "-casdeploy")
|
||||
DeployProviderTypeAliyunCDN = DeployProviderType(AccessProviderTypeAliyun + "-cdn")
|
||||
DeployProviderTypeAliyunCLB = DeployProviderType(AccessProviderTypeAliyun + "-clb")
|
||||
DeployProviderTypeAliyunDCDN = DeployProviderType(AccessProviderTypeAliyun + "-dcdn")
|
||||
DeployProviderTypeAliyunESA = DeployProviderType(AccessProviderTypeAliyun + "-esa")
|
||||
DeployProviderTypeAliyunFC = DeployProviderType(AccessProviderTypeAliyun + "-fc")
|
||||
DeployProviderTypeAliyunLive = DeployProviderType(AccessProviderTypeAliyun + "-live")
|
||||
DeployProviderTypeAliyunNLB = DeployProviderType(AccessProviderTypeAliyun + "-nlb")
|
||||
DeployProviderTypeAliyunOSS = DeployProviderType(AccessProviderTypeAliyun + "-oss")
|
||||
DeployProviderTypeAliyunVOD = DeployProviderType(AccessProviderTypeAliyun + "-vod")
|
||||
DeployProviderTypeAliyunWAF = DeployProviderType(AccessProviderTypeAliyun + "-waf")
|
||||
DeployProviderTypeAWSACM = DeployProviderType(AccessProviderTypeAWS + "-acm")
|
||||
DeployProviderTypeAWSCloudFront = DeployProviderType(AccessProviderTypeAWS + "-cloudfront")
|
||||
DeployProviderTypeAzureKeyVault = DeployProviderType(AccessProviderTypeAzure + "-keyvault")
|
||||
DeployProviderTypeBaiduCloudAppBLB = DeployProviderType(AccessProviderTypeBaiduCloud + "-appblb")
|
||||
DeployProviderTypeBaiduCloudBLB = DeployProviderType(AccessProviderTypeBaiduCloud + "-blb")
|
||||
DeployProviderTypeBaiduCloudCDN = DeployProviderType(AccessProviderTypeBaiduCloud + "-cdn")
|
||||
DeployProviderTypeBaiduCloudCert = DeployProviderType(AccessProviderTypeBaiduCloud + "-cert")
|
||||
DeployProviderTypeBaishanCDN = DeployProviderType(AccessProviderTypeBaishan + "-cdn")
|
||||
DeployProviderTypeBaotaPanelConsole = DeployProviderType(AccessProviderTypeBaotaPanel + "-console")
|
||||
DeployProviderTypeBaotaPanelSite = DeployProviderType(AccessProviderTypeBaotaPanel + "-site")
|
||||
DeployProviderTypeBunnyCDN = DeployProviderType(AccessProviderTypeBunny + "-cdn")
|
||||
DeployProviderTypeBytePlusCDN = DeployProviderType(AccessProviderTypeBytePlus + "-cdn")
|
||||
DeployProviderTypeCacheFly = DeployProviderType(AccessProviderTypeCacheFly)
|
||||
DeployProviderTypeCdnfly = DeployProviderType(AccessProviderTypeCdnfly)
|
||||
DeployProviderTypeDogeCloudCDN = DeployProviderType(AccessProviderTypeDogeCloud + "-cdn")
|
||||
DeployProviderTypeEdgioApplications = DeployProviderType(AccessProviderTypeEdgio + "-applications")
|
||||
DeployProviderTypeGcoreCDN = DeployProviderType(AccessProviderTypeGcore + "-cdn")
|
||||
DeployProviderTypeHuaweiCloudCDN = DeployProviderType(AccessProviderTypeHuaweiCloud + "-cdn")
|
||||
DeployProviderTypeHuaweiCloudELB = DeployProviderType(AccessProviderTypeHuaweiCloud + "-elb")
|
||||
DeployProviderTypeHuaweiCloudSCM = DeployProviderType(AccessProviderTypeHuaweiCloud + "-scm")
|
||||
DeployProviderTypeHuaweiCloudWAF = DeployProviderType(AccessProviderTypeHuaweiCloud + "-waf")
|
||||
DeployProviderTypeJDCloudALB = DeployProviderType(AccessProviderTypeJDCloud + "-alb")
|
||||
DeployProviderTypeJDCloudCDN = DeployProviderType(AccessProviderTypeJDCloud + "-cdn")
|
||||
DeployProviderTypeJDCloudLive = DeployProviderType(AccessProviderTypeJDCloud + "-live")
|
||||
DeployProviderTypeJDCloudVOD = DeployProviderType(AccessProviderTypeJDCloud + "-vod")
|
||||
DeployProviderTypeKubernetesSecret = DeployProviderType(AccessProviderTypeKubernetes + "-secret")
|
||||
DeployProviderTypeLocal = DeployProviderType(AccessProviderTypeLocal)
|
||||
DeployProviderTypeQiniuCDN = DeployProviderType(AccessProviderTypeQiniu + "-cdn")
|
||||
DeployProviderTypeQiniuKodo = DeployProviderType(AccessProviderTypeQiniu + "-kodo")
|
||||
DeployProviderTypeQiniuPili = DeployProviderType(AccessProviderTypeQiniu + "-pili")
|
||||
DeployProviderTypeRainYunRCDN = DeployProviderType(AccessProviderTypeRainYun + "-rcdn")
|
||||
DeployProviderTypeSafeLine = DeployProviderType(AccessProviderTypeSafeLine)
|
||||
DeployProviderTypeSSH = DeployProviderType(AccessProviderTypeSSH)
|
||||
DeployProviderTypeTencentCloudCDN = DeployProviderType(AccessProviderTypeTencentCloud + "-cdn")
|
||||
DeployProviderTypeTencentCloudCLB = DeployProviderType(AccessProviderTypeTencentCloud + "-clb")
|
||||
DeployProviderTypeTencentCloudCOS = DeployProviderType(AccessProviderTypeTencentCloud + "-cos")
|
||||
DeployProviderTypeTencentCloudCSS = DeployProviderType(AccessProviderTypeTencentCloud + "-css")
|
||||
DeployProviderTypeTencentCloudECDN = DeployProviderType(AccessProviderTypeTencentCloud + "-ecdn")
|
||||
DeployProviderTypeTencentCloudEO = DeployProviderType(AccessProviderTypeTencentCloud + "-eo")
|
||||
DeployProviderTypeTencentCloudSCF = DeployProviderType(AccessProviderTypeTencentCloud + "-scf")
|
||||
DeployProviderTypeTencentCloudSSL = DeployProviderType(AccessProviderTypeTencentCloud + "-ssl")
|
||||
DeployProviderTypeTencentCloudSSLDeploy = DeployProviderType(AccessProviderTypeTencentCloud + "-ssldeploy")
|
||||
DeployProviderTypeTencentCloudVOD = DeployProviderType(AccessProviderTypeTencentCloud + "-vod")
|
||||
DeployProviderTypeTencentCloudWAF = DeployProviderType(AccessProviderTypeTencentCloud + "-waf")
|
||||
DeployProviderTypeUCloudUCDN = DeployProviderType(AccessProviderTypeUCloud + "-ucdn")
|
||||
DeployProviderTypeUCloudUS3 = DeployProviderType(AccessProviderTypeUCloud + "-us3")
|
||||
DeployProviderTypeUpyunCDN = DeployProviderType(AccessProviderTypeUpyun + "-cdn")
|
||||
DeployProviderTypeUpyunFile = DeployProviderType(AccessProviderTypeUpyun + "-file")
|
||||
DeployProviderTypeVolcEngineALB = DeployProviderType(AccessProviderTypeVolcEngine + "-alb")
|
||||
DeployProviderTypeVolcEngineCDN = DeployProviderType(AccessProviderTypeVolcEngine + "-cdn")
|
||||
DeployProviderTypeVolcEngineCertCenter = DeployProviderType(AccessProviderTypeVolcEngine + "-certcenter")
|
||||
DeployProviderTypeVolcEngineCLB = DeployProviderType(AccessProviderTypeVolcEngine + "-clb")
|
||||
DeployProviderTypeVolcEngineDCDN = DeployProviderType(AccessProviderTypeVolcEngine + "-dcdn")
|
||||
DeployProviderTypeVolcEngineImageX = DeployProviderType(AccessProviderTypeVolcEngine + "-imagex")
|
||||
DeployProviderTypeVolcEngineLive = DeployProviderType(AccessProviderTypeVolcEngine + "-live")
|
||||
DeployProviderTypeVolcEngineTOS = DeployProviderType(AccessProviderTypeVolcEngine + "-tos")
|
||||
DeployProviderTypeWangsuCDNPro = DeployProviderType(AccessProviderTypeWangsu + "-cdnpro")
|
||||
DeployProviderTypeWebhook = DeployProviderType(AccessProviderTypeWebhook)
|
||||
)
|
||||
|
||||
type NotifyProviderType string
|
||||
|
||||
/*
|
||||
消息通知提供商常量值。
|
||||
短横线前的部分始终等于授权提供商类型。
|
||||
|
||||
注意:如果追加新的常量值,请保持以 ASCII 排序。
|
||||
NOTICE: If you add new constant, please keep ASCII order.
|
||||
*/
|
||||
const (
|
||||
NotifyProviderTypeWebhook = NotifyProviderType(AccessProviderTypeWebhook)
|
||||
)
|
||||
|
@ -13,6 +13,7 @@ type Settings struct {
|
||||
Content string `json:"content" db:"content"`
|
||||
}
|
||||
|
||||
// Deprecated: v0.4.x 将废弃
|
||||
type NotifyTemplatesSettingsContent struct {
|
||||
NotifyTemplates []struct {
|
||||
Subject string `json:"subject"`
|
||||
@ -20,8 +21,10 @@ type NotifyTemplatesSettingsContent struct {
|
||||
} `json:"notifyTemplates"`
|
||||
}
|
||||
|
||||
// Deprecated: v0.4.x 将废弃
|
||||
type NotifyChannelsSettingsContent map[string]map[string]any
|
||||
|
||||
// Deprecated: v0.4.x 将废弃
|
||||
func (s *Settings) GetNotifyChannelConfig(channel string) (map[string]any, error) {
|
||||
conf := &NotifyChannelsSettingsContent{}
|
||||
if err := json.Unmarshal([]byte(s.Content), conf); err != nil {
|
||||
|
@ -71,7 +71,7 @@ type WorkflowNodeConfigForApply struct {
|
||||
CAProvider string `json:"caProvider,omitempty"` // CA 提供商(零值将使用全局配置)
|
||||
CAProviderAccessId string `json:"caProviderAccessId,omitempty"` // CA 提供商授权记录 ID
|
||||
CAProviderConfig map[string]any `json:"caProviderConfig,omitempty"` // CA 提供商额外配置
|
||||
KeyAlgorithm string `json:"keyAlgorithm"` // 密钥算法
|
||||
KeyAlgorithm string `json:"keyAlgorithm"` // 证书算法
|
||||
Nameservers string `json:"nameservers,omitempty"` // DNS 服务器列表,以半角分号分隔
|
||||
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` // DNS 传播超时时间(零值取决于提供商的默认值)
|
||||
DnsTTL int32 `json:"dnsTTL,omitempty"` // DNS TTL(零值取决于提供商的默认值)
|
||||
@ -95,9 +95,12 @@ type WorkflowNodeConfigForDeploy struct {
|
||||
}
|
||||
|
||||
type WorkflowNodeConfigForNotify struct {
|
||||
Channel string `json:"channel"` // 通知渠道
|
||||
Subject string `json:"subject"` // 通知主题
|
||||
Message string `json:"message"` // 通知内容
|
||||
Channel string `json:"channel,omitempty"` // Deprecated: v0.4.x 将废弃
|
||||
Provider string `json:"provider"` // 通知提供商
|
||||
ProviderAccessId string `json:"providerAccessId"` // 通知提供商授权记录 ID
|
||||
ProviderConfig map[string]any `json:"providerConfig,omitempty"` // 通知提供商额外配置
|
||||
Subject string `json:"subject"` // 通知主题
|
||||
Message string `json:"message"` // 通知内容
|
||||
}
|
||||
|
||||
func (n *WorkflowNode) GetConfigForApply() WorkflowNodeConfigForApply {
|
||||
@ -111,10 +114,10 @@ func (n *WorkflowNode) GetConfigForApply() WorkflowNodeConfigForApply {
|
||||
ContactEmail: maputil.GetString(n.Config, "contactEmail"),
|
||||
Provider: maputil.GetString(n.Config, "provider"),
|
||||
ProviderAccessId: maputil.GetString(n.Config, "providerAccessId"),
|
||||
ProviderConfig: maputil.GetAnyMap(n.Config, "providerConfig"),
|
||||
ProviderConfig: maputil.GetMap(n.Config, "providerConfig"),
|
||||
CAProvider: maputil.GetString(n.Config, "caProvider"),
|
||||
CAProviderAccessId: maputil.GetString(n.Config, "caProviderAccessId"),
|
||||
CAProviderConfig: maputil.GetAnyMap(n.Config, "caProviderConfig"),
|
||||
CAProviderConfig: maputil.GetMap(n.Config, "caProviderConfig"),
|
||||
KeyAlgorithm: maputil.GetString(n.Config, "keyAlgorithm"),
|
||||
Nameservers: maputil.GetString(n.Config, "nameservers"),
|
||||
DnsPropagationTimeout: maputil.GetInt32(n.Config, "dnsPropagationTimeout"),
|
||||
@ -138,16 +141,19 @@ func (n *WorkflowNode) GetConfigForDeploy() WorkflowNodeConfigForDeploy {
|
||||
Certificate: maputil.GetString(n.Config, "certificate"),
|
||||
Provider: maputil.GetString(n.Config, "provider"),
|
||||
ProviderAccessId: maputil.GetString(n.Config, "providerAccessId"),
|
||||
ProviderConfig: maputil.GetAnyMap(n.Config, "providerConfig"),
|
||||
ProviderConfig: maputil.GetMap(n.Config, "providerConfig"),
|
||||
SkipOnLastSucceeded: maputil.GetBool(n.Config, "skipOnLastSucceeded"),
|
||||
}
|
||||
}
|
||||
|
||||
func (n *WorkflowNode) GetConfigForNotify() WorkflowNodeConfigForNotify {
|
||||
return WorkflowNodeConfigForNotify{
|
||||
Channel: maputil.GetString(n.Config, "channel"),
|
||||
Subject: maputil.GetString(n.Config, "subject"),
|
||||
Message: maputil.GetString(n.Config, "message"),
|
||||
Channel: maputil.GetString(n.Config, "channel"),
|
||||
Provider: maputil.GetString(n.Config, "provider"),
|
||||
ProviderAccessId: maputil.GetString(n.Config, "providerAccessId"),
|
||||
ProviderConfig: maputil.GetMap(n.Config, "providerConfig"),
|
||||
Subject: maputil.GetString(n.Config, "subject"),
|
||||
Message: maputil.GetString(n.Config, "message"),
|
||||
}
|
||||
}
|
||||
|
||||
|
72
internal/notify/notifier.go
Normal file
72
internal/notify/notifier.go
Normal file
@ -0,0 +1,72 @@
|
||||
package notify
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/usual2970/certimate/internal/domain"
|
||||
"github.com/usual2970/certimate/internal/pkg/core/notifier"
|
||||
"github.com/usual2970/certimate/internal/repository"
|
||||
)
|
||||
|
||||
type Notifier interface {
|
||||
Notify(ctx context.Context) error
|
||||
}
|
||||
|
||||
type NotifierWithWorkflowNodeConfig struct {
|
||||
Node *domain.WorkflowNode
|
||||
Logger *slog.Logger
|
||||
Subject string
|
||||
Message string
|
||||
}
|
||||
|
||||
func NewWithWorkflowNode(config NotifierWithWorkflowNodeConfig) (Notifier, error) {
|
||||
if config.Node == nil {
|
||||
return nil, fmt.Errorf("node is nil")
|
||||
}
|
||||
if config.Node.Type != domain.WorkflowNodeTypeNotify {
|
||||
return nil, fmt.Errorf("node type is not '%s'", string(domain.WorkflowNodeTypeNotify))
|
||||
}
|
||||
|
||||
nodeConfig := config.Node.GetConfigForNotify()
|
||||
options := ¬ifierProviderOptions{
|
||||
Provider: domain.NotifyProviderType(nodeConfig.Provider),
|
||||
ProviderAccessConfig: make(map[string]any),
|
||||
ProviderNotifyConfig: nodeConfig.ProviderConfig,
|
||||
}
|
||||
|
||||
accessRepo := repository.NewAccessRepository()
|
||||
if nodeConfig.ProviderAccessId != "" {
|
||||
access, err := accessRepo.GetById(context.Background(), nodeConfig.ProviderAccessId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get access #%s record: %w", nodeConfig.ProviderAccessId, err)
|
||||
} else {
|
||||
options.ProviderAccessConfig = access.Config
|
||||
}
|
||||
}
|
||||
|
||||
notifierProvider, err := createNotifierProvider(options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ¬ifierImpl{
|
||||
provider: notifierProvider.WithLogger(config.Logger),
|
||||
subject: config.Subject,
|
||||
message: config.Message,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type notifierImpl struct {
|
||||
provider notifier.Notifier
|
||||
subject string
|
||||
message string
|
||||
}
|
||||
|
||||
var _ Notifier = (*notifierImpl)(nil)
|
||||
|
||||
func (n *notifierImpl) Notify(ctx context.Context) error {
|
||||
_, err := n.provider.Notify(ctx, n.subject, n.message)
|
||||
return err
|
||||
}
|
@ -13,6 +13,7 @@ import (
|
||||
"github.com/usual2970/certimate/internal/repository"
|
||||
)
|
||||
|
||||
// Deprecated: v0.4.x 将废弃
|
||||
func SendToAllChannels(subject, message string) error {
|
||||
notifiers, err := getEnabledNotifiers()
|
||||
if err != nil {
|
||||
@ -38,8 +39,9 @@ func SendToAllChannels(subject, message string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Deprecated: v0.4.x 将废弃
|
||||
func SendToChannel(subject, message string, channel string, channelConfig map[string]any) error {
|
||||
notifier, err := createNotifier(domain.NotifyChannelType(channel), channelConfig)
|
||||
notifier, err := createNotifierProviderUseGlobalSettings(domain.NotifyChannelType(channel), channelConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -48,6 +50,7 @@ func SendToChannel(subject, message string, channel string, channelConfig map[st
|
||||
return err
|
||||
}
|
||||
|
||||
// Deprecated: v0.4.x 将废弃
|
||||
func getEnabledNotifiers() ([]notifier.Notifier, error) {
|
||||
settingsRepo := repository.NewSettingsRepository()
|
||||
settings, err := settingsRepo.GetByName(context.Background(), "notifyChannels")
|
||||
@ -66,7 +69,7 @@ func getEnabledNotifiers() ([]notifier.Notifier, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
notifier, err := createNotifier(domain.NotifyChannelType(k), v)
|
||||
notifier, err := createNotifierProviderUseGlobalSettings(domain.NotifyChannelType(k), v)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
@ -5,102 +5,28 @@ import (
|
||||
|
||||
"github.com/usual2970/certimate/internal/domain"
|
||||
"github.com/usual2970/certimate/internal/pkg/core/notifier"
|
||||
pBark "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/bark"
|
||||
pDingTalk "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/dingtalk"
|
||||
pEmail "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/email"
|
||||
pGotify "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/gotify"
|
||||
pLark "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/lark"
|
||||
pMattermost "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/mattermost"
|
||||
pPushover "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/pushover"
|
||||
pPushPlus "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/pushplus"
|
||||
pServerChan "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/serverchan"
|
||||
pTelegram "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/telegram"
|
||||
pWebhook "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/webhook"
|
||||
pWeCom "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/wecom"
|
||||
maputil "github.com/usual2970/certimate/internal/pkg/utils/map"
|
||||
)
|
||||
|
||||
func createNotifier(channel domain.NotifyChannelType, channelConfig map[string]any) (notifier.Notifier, error) {
|
||||
type notifierProviderOptions struct {
|
||||
Provider domain.NotifyProviderType
|
||||
ProviderAccessConfig map[string]any
|
||||
ProviderNotifyConfig map[string]any
|
||||
}
|
||||
|
||||
func createNotifierProvider(options *notifierProviderOptions) (notifier.Notifier, error) {
|
||||
/*
|
||||
注意:如果追加新的常量值,请保持以 ASCII 排序。
|
||||
NOTICE: If you add new constant, please keep ASCII order.
|
||||
*/
|
||||
switch channel {
|
||||
case domain.NotifyChannelTypeBark:
|
||||
return pBark.NewNotifier(&pBark.NotifierConfig{
|
||||
DeviceKey: maputil.GetString(channelConfig, "deviceKey"),
|
||||
ServerUrl: maputil.GetString(channelConfig, "serverUrl"),
|
||||
})
|
||||
|
||||
case domain.NotifyChannelTypeDingTalk:
|
||||
return pDingTalk.NewNotifier(&pDingTalk.NotifierConfig{
|
||||
AccessToken: maputil.GetString(channelConfig, "accessToken"),
|
||||
Secret: maputil.GetString(channelConfig, "secret"),
|
||||
})
|
||||
|
||||
case domain.NotifyChannelTypeEmail:
|
||||
return pEmail.NewNotifier(&pEmail.NotifierConfig{
|
||||
SmtpHost: maputil.GetString(channelConfig, "smtpHost"),
|
||||
SmtpPort: maputil.GetInt32(channelConfig, "smtpPort"),
|
||||
SmtpTLS: maputil.GetOrDefaultBool(channelConfig, "smtpTLS", true),
|
||||
Username: maputil.GetOrDefaultString(channelConfig, "username", maputil.GetString(channelConfig, "senderAddress")),
|
||||
Password: maputil.GetString(channelConfig, "password"),
|
||||
SenderAddress: maputil.GetString(channelConfig, "senderAddress"),
|
||||
ReceiverAddress: maputil.GetString(channelConfig, "receiverAddress"),
|
||||
})
|
||||
|
||||
case domain.NotifyChannelTypeGotify:
|
||||
return pGotify.NewNotifier(&pGotify.NotifierConfig{
|
||||
Url: maputil.GetString(channelConfig, "url"),
|
||||
Token: maputil.GetString(channelConfig, "token"),
|
||||
Priority: maputil.GetOrDefaultInt64(channelConfig, "priority", 1),
|
||||
})
|
||||
|
||||
case domain.NotifyChannelTypeLark:
|
||||
return pLark.NewNotifier(&pLark.NotifierConfig{
|
||||
WebhookUrl: maputil.GetString(channelConfig, "webhookUrl"),
|
||||
})
|
||||
|
||||
case domain.NotifyChannelTypeMattermost:
|
||||
return pMattermost.NewNotifier(&pMattermost.NotifierConfig{
|
||||
ServerUrl: maputil.GetString(channelConfig, "serverUrl"),
|
||||
ChannelId: maputil.GetString(channelConfig, "channelId"),
|
||||
Username: maputil.GetString(channelConfig, "username"),
|
||||
Password: maputil.GetString(channelConfig, "password"),
|
||||
})
|
||||
case domain.NotifyChannelTypePushover:
|
||||
return pPushover.NewNotifier(&pPushover.NotifierConfig{
|
||||
Token: maputil.GetString(channelConfig, "token"),
|
||||
User: maputil.GetString(channelConfig, "user"),
|
||||
})
|
||||
|
||||
case domain.NotifyChannelTypePushPlus:
|
||||
return pPushPlus.NewNotifier(&pPushPlus.NotifierConfig{
|
||||
Token: maputil.GetString(channelConfig, "token"),
|
||||
})
|
||||
|
||||
case domain.NotifyChannelTypeServerChan:
|
||||
return pServerChan.NewNotifier(&pServerChan.NotifierConfig{
|
||||
Url: maputil.GetString(channelConfig, "url"),
|
||||
})
|
||||
|
||||
case domain.NotifyChannelTypeTelegram:
|
||||
return pTelegram.NewNotifier(&pTelegram.NotifierConfig{
|
||||
ApiToken: maputil.GetString(channelConfig, "apiToken"),
|
||||
ChatId: maputil.GetInt64(channelConfig, "chatId"),
|
||||
})
|
||||
|
||||
case domain.NotifyChannelTypeWebhook:
|
||||
switch options.Provider {
|
||||
case domain.NotifyProviderTypeWebhook:
|
||||
return pWebhook.NewNotifier(&pWebhook.NotifierConfig{
|
||||
Url: maputil.GetString(channelConfig, "url"),
|
||||
AllowInsecureConnections: maputil.GetBool(channelConfig, "allowInsecureConnections"),
|
||||
})
|
||||
|
||||
case domain.NotifyChannelTypeWeCom:
|
||||
return pWeCom.NewNotifier(&pWeCom.NotifierConfig{
|
||||
WebhookUrl: maputil.GetString(channelConfig, "webhookUrl"),
|
||||
Url: maputil.GetString(options.ProviderAccessConfig, "url"),
|
||||
AllowInsecureConnections: maputil.GetBool(options.ProviderAccessConfig, "allowInsecureConnections"),
|
||||
})
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unsupported notifier channel '%s'", channelConfig)
|
||||
return nil, fmt.Errorf("unsupported notifier provider '%s'", options.Provider)
|
||||
}
|
||||
|
108
internal/notify/providers_deprecated.go
Normal file
108
internal/notify/providers_deprecated.go
Normal file
@ -0,0 +1,108 @@
|
||||
package notify
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/usual2970/certimate/internal/domain"
|
||||
"github.com/usual2970/certimate/internal/pkg/core/notifier"
|
||||
pBark "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/bark"
|
||||
pDingTalk "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/dingtalk"
|
||||
pEmail "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/email"
|
||||
pGotify "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/gotify"
|
||||
pLark "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/lark"
|
||||
pMattermost "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/mattermost"
|
||||
pPushover "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/pushover"
|
||||
pPushPlus "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/pushplus"
|
||||
pServerChan "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/serverchan"
|
||||
pTelegram "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/telegram"
|
||||
pWebhook "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/webhook"
|
||||
pWeCom "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/wecom"
|
||||
maputil "github.com/usual2970/certimate/internal/pkg/utils/map"
|
||||
)
|
||||
|
||||
// Deprecated: v0.4.x 将废弃
|
||||
func createNotifierProviderUseGlobalSettings(channel domain.NotifyChannelType, channelConfig map[string]any) (notifier.Notifier, error) {
|
||||
/*
|
||||
注意:如果追加新的常量值,请保持以 ASCII 排序。
|
||||
NOTICE: If you add new constant, please keep ASCII order.
|
||||
*/
|
||||
switch channel {
|
||||
case domain.NotifyChannelTypeBark:
|
||||
return pBark.NewNotifier(&pBark.NotifierConfig{
|
||||
DeviceKey: maputil.GetString(channelConfig, "deviceKey"),
|
||||
ServerUrl: maputil.GetString(channelConfig, "serverUrl"),
|
||||
})
|
||||
|
||||
case domain.NotifyChannelTypeDingTalk:
|
||||
return pDingTalk.NewNotifier(&pDingTalk.NotifierConfig{
|
||||
AccessToken: maputil.GetString(channelConfig, "accessToken"),
|
||||
Secret: maputil.GetString(channelConfig, "secret"),
|
||||
})
|
||||
|
||||
case domain.NotifyChannelTypeEmail:
|
||||
return pEmail.NewNotifier(&pEmail.NotifierConfig{
|
||||
SmtpHost: maputil.GetString(channelConfig, "smtpHost"),
|
||||
SmtpPort: maputil.GetInt32(channelConfig, "smtpPort"),
|
||||
SmtpTLS: maputil.GetOrDefaultBool(channelConfig, "smtpTLS", true),
|
||||
Username: maputil.GetOrDefaultString(channelConfig, "username", maputil.GetString(channelConfig, "senderAddress")),
|
||||
Password: maputil.GetString(channelConfig, "password"),
|
||||
SenderAddress: maputil.GetString(channelConfig, "senderAddress"),
|
||||
ReceiverAddress: maputil.GetString(channelConfig, "receiverAddress"),
|
||||
})
|
||||
|
||||
case domain.NotifyChannelTypeGotify:
|
||||
return pGotify.NewNotifier(&pGotify.NotifierConfig{
|
||||
Url: maputil.GetString(channelConfig, "url"),
|
||||
Token: maputil.GetString(channelConfig, "token"),
|
||||
Priority: maputil.GetOrDefaultInt64(channelConfig, "priority", 1),
|
||||
})
|
||||
|
||||
case domain.NotifyChannelTypeLark:
|
||||
return pLark.NewNotifier(&pLark.NotifierConfig{
|
||||
WebhookUrl: maputil.GetString(channelConfig, "webhookUrl"),
|
||||
})
|
||||
|
||||
case domain.NotifyChannelTypeMattermost:
|
||||
return pMattermost.NewNotifier(&pMattermost.NotifierConfig{
|
||||
ServerUrl: maputil.GetString(channelConfig, "serverUrl"),
|
||||
ChannelId: maputil.GetString(channelConfig, "channelId"),
|
||||
Username: maputil.GetString(channelConfig, "username"),
|
||||
Password: maputil.GetString(channelConfig, "password"),
|
||||
})
|
||||
|
||||
case domain.NotifyChannelTypePushover:
|
||||
return pPushover.NewNotifier(&pPushover.NotifierConfig{
|
||||
Token: maputil.GetString(channelConfig, "token"),
|
||||
User: maputil.GetString(channelConfig, "user"),
|
||||
})
|
||||
|
||||
case domain.NotifyChannelTypePushPlus:
|
||||
return pPushPlus.NewNotifier(&pPushPlus.NotifierConfig{
|
||||
Token: maputil.GetString(channelConfig, "token"),
|
||||
})
|
||||
|
||||
case domain.NotifyChannelTypeServerChan:
|
||||
return pServerChan.NewNotifier(&pServerChan.NotifierConfig{
|
||||
Url: maputil.GetString(channelConfig, "url"),
|
||||
})
|
||||
|
||||
case domain.NotifyChannelTypeTelegram:
|
||||
return pTelegram.NewNotifier(&pTelegram.NotifierConfig{
|
||||
ApiToken: maputil.GetString(channelConfig, "apiToken"),
|
||||
ChatId: maputil.GetInt64(channelConfig, "chatId"),
|
||||
})
|
||||
|
||||
case domain.NotifyChannelTypeWebhook:
|
||||
return pWebhook.NewNotifier(&pWebhook.NotifierConfig{
|
||||
Url: maputil.GetString(channelConfig, "url"),
|
||||
AllowInsecureConnections: maputil.GetBool(channelConfig, "allowInsecureConnections"),
|
||||
})
|
||||
|
||||
case domain.NotifyChannelTypeWeCom:
|
||||
return pWeCom.NewNotifier(&pWeCom.NotifierConfig{
|
||||
WebhookUrl: maputil.GetString(channelConfig, "webhookUrl"),
|
||||
})
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unsupported notifier channel '%s'", channelConfig)
|
||||
}
|
@ -8,25 +8,30 @@ import (
|
||||
"github.com/usual2970/certimate/internal/domain/dtos"
|
||||
)
|
||||
|
||||
// Deprecated: v0.4.x 将废弃
|
||||
const (
|
||||
notifyTestTitle = "测试通知"
|
||||
notifyTestBody = "欢迎使用 Certimate ,这是一条测试通知。"
|
||||
)
|
||||
|
||||
// Deprecated: v0.4.x 将废弃
|
||||
type settingsRepository interface {
|
||||
GetByName(ctx context.Context, name string) (*domain.Settings, error)
|
||||
}
|
||||
|
||||
// Deprecated: v0.4.x 将废弃
|
||||
type NotifyService struct {
|
||||
settingsRepo settingsRepository
|
||||
}
|
||||
|
||||
// Deprecated: v0.4.x 将废弃
|
||||
func NewNotifyService(settingsRepo settingsRepository) *NotifyService {
|
||||
return &NotifyService{
|
||||
settingsRepo: settingsRepo,
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated: v0.4.x 将废弃
|
||||
func (n *NotifyService) Test(ctx context.Context, req *dtos.NotifyTestPushReq) error {
|
||||
settings, err := n.settingsRepo.GetByName(ctx, "notifyChannels")
|
||||
if err != nil {
|
||||
|
@ -207,7 +207,7 @@ func GetOrDefaultBool(dict map[string]any, key string, defaultValue bool) bool {
|
||||
//
|
||||
// 出参:
|
||||
// - 字典中键对应的 `map[string]any` 对象。
|
||||
func GetAnyMap(dict map[string]any, key string) map[string]any {
|
||||
func GetMap(dict map[string]any, key string) map[string]any {
|
||||
if dict == nil {
|
||||
return make(map[string]any)
|
||||
}
|
||||
|
@ -49,14 +49,17 @@ func (n *applyNode) Process(ctx context.Context) error {
|
||||
}
|
||||
|
||||
// 初始化申请器
|
||||
applicant, err := applicant.NewWithApplyNode(n.node)
|
||||
applicant, err := applicant.NewWithWorkflowNode(applicant.ApplicantWithWorkflowNodeConfig{
|
||||
Node: n.node,
|
||||
Logger: n.logger,
|
||||
})
|
||||
if err != nil {
|
||||
n.logger.Warn("failed to create applicant provider")
|
||||
return err
|
||||
}
|
||||
|
||||
// 申请证书
|
||||
applyResult, err := applicant.Apply()
|
||||
applyResult, err := applicant.Apply(ctx)
|
||||
if err != nil {
|
||||
n.logger.Warn("failed to apply")
|
||||
return err
|
||||
|
@ -63,17 +63,18 @@ func (n *deployNode) Process(ctx context.Context) error {
|
||||
}
|
||||
|
||||
// 初始化部署器
|
||||
deployer, err := deployer.NewWithDeployNode(n.node, struct {
|
||||
Certificate string
|
||||
PrivateKey string
|
||||
}{Certificate: certificate.Certificate, PrivateKey: certificate.PrivateKey})
|
||||
deployer, err := deployer.NewWithWorkflowNode(deployer.DeployerWithWorkflowNodeConfig{
|
||||
Node: n.node,
|
||||
Logger: n.logger,
|
||||
CertificatePEM: certificate.Certificate,
|
||||
PrivateKeyPEM: certificate.PrivateKey,
|
||||
})
|
||||
if err != nil {
|
||||
n.logger.Warn("failed to create deployer provider")
|
||||
return err
|
||||
}
|
||||
|
||||
// 部署证书
|
||||
deployer.SetLogger(n.logger)
|
||||
if err := deployer.Deploy(ctx); err != nil {
|
||||
n.logger.Warn("failed to deploy")
|
||||
return err
|
||||
|
@ -30,25 +30,50 @@ func (n *notifyNode) Process(ctx context.Context) error {
|
||||
|
||||
nodeConfig := n.node.GetConfigForNotify()
|
||||
|
||||
// 获取通知配置
|
||||
settings, err := n.settingsRepo.GetByName(ctx, "notifyChannels")
|
||||
if nodeConfig.Provider == "" {
|
||||
// Deprecated: v0.4.x 将废弃
|
||||
// 兼容旧版本的通知渠道
|
||||
n.logger.Warn("WARNING! you are using the notification channel from global settings, which will be deprecated in the future")
|
||||
|
||||
// 获取通知配置
|
||||
settings, err := n.settingsRepo.GetByName(ctx, "notifyChannels")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 获取通知渠道
|
||||
channelConfig, err := settings.GetNotifyChannelConfig(nodeConfig.Channel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 发送通知
|
||||
if err := notify.SendToChannel(nodeConfig.Subject, nodeConfig.Message, nodeConfig.Channel, channelConfig); err != nil {
|
||||
n.logger.Warn("failed to notify", slog.String("channel", nodeConfig.Channel))
|
||||
return err
|
||||
}
|
||||
|
||||
n.logger.Info("notify completed")
|
||||
return nil
|
||||
}
|
||||
|
||||
// 初始化通知器
|
||||
deployer, err := notify.NewWithWorkflowNode(notify.NotifierWithWorkflowNodeConfig{
|
||||
Node: n.node,
|
||||
Logger: n.logger,
|
||||
Subject: nodeConfig.Subject,
|
||||
Message: nodeConfig.Message,
|
||||
})
|
||||
if err != nil {
|
||||
n.logger.Warn("failed to create notifier provider")
|
||||
return err
|
||||
}
|
||||
|
||||
// 获取通知渠道
|
||||
channelConfig, err := settings.GetNotifyChannelConfig(nodeConfig.Channel)
|
||||
if err != nil {
|
||||
// 推送通知
|
||||
if err := deployer.Notify(ctx); err != nil {
|
||||
n.logger.Warn("failed to notify")
|
||||
return err
|
||||
}
|
||||
|
||||
// 发送通知
|
||||
if err := notify.SendToChannel(nodeConfig.Subject, nodeConfig.Message, nodeConfig.Channel, channelConfig); err != nil {
|
||||
n.logger.Warn("failed to notify", slog.String("channel", nodeConfig.Channel))
|
||||
return err
|
||||
}
|
||||
|
||||
n.logger.Info("notify completed")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
67
ui/src/components/provider/NotifyProviderSelect.tsx
Normal file
67
ui/src/components/provider/NotifyProviderSelect.tsx
Normal file
@ -0,0 +1,67 @@
|
||||
import { memo, useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Avatar, Select, type SelectProps, Space, Typography } from "antd";
|
||||
|
||||
import { type NotifyProvider, notifyProvidersMap } from "@/domain/provider";
|
||||
|
||||
export type NotifyProviderSelectProps = Omit<
|
||||
SelectProps,
|
||||
"filterOption" | "filterSort" | "labelRender" | "options" | "optionFilterProp" | "optionLabelProp" | "optionRender"
|
||||
> & {
|
||||
filter?: (record: NotifyProvider) => boolean;
|
||||
};
|
||||
|
||||
const NotifyProviderSelect = ({ filter, ...props }: NotifyProviderSelectProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [options, setOptions] = useState<Array<{ key: string; value: string; label: string; data: NotifyProvider }>>([]);
|
||||
useEffect(() => {
|
||||
const allItems = Array.from(notifyProvidersMap.values());
|
||||
const filteredItems = filter != null ? allItems.filter(filter) : allItems;
|
||||
setOptions(
|
||||
filteredItems.map((item) => ({
|
||||
key: item.type,
|
||||
value: item.type,
|
||||
label: t(item.name),
|
||||
data: item,
|
||||
}))
|
||||
);
|
||||
}, [filter]);
|
||||
|
||||
const renderOption = (key: string) => {
|
||||
const provider = notifyProvidersMap.get(key);
|
||||
return (
|
||||
<Space className="max-w-full grow overflow-hidden truncate" size={4}>
|
||||
<Avatar src={provider?.icon} size="small" />
|
||||
<Typography.Text className="leading-loose" ellipsis>
|
||||
{t(provider?.name ?? "")}
|
||||
</Typography.Text>
|
||||
</Space>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Select
|
||||
{...props}
|
||||
filterOption={(inputValue, option) => {
|
||||
if (!option) return false;
|
||||
|
||||
const value = inputValue.toLowerCase();
|
||||
return option.value.toLowerCase().includes(value) || option.label.toLowerCase().includes(value);
|
||||
}}
|
||||
labelRender={({ label, value }) => {
|
||||
if (!label) {
|
||||
return <Typography.Text type="secondary">{props.placeholder}</Typography.Text>;
|
||||
}
|
||||
|
||||
return renderOption(value as string);
|
||||
}}
|
||||
options={options}
|
||||
optionFilterProp={undefined}
|
||||
optionLabelProp={undefined}
|
||||
optionRender={(option) => renderOption(option.data.value)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(NotifyProviderSelect);
|
@ -193,6 +193,7 @@ const WorkflowRunLogs = ({ runId, runStatus }: { runId: string; runStatus: strin
|
||||
const NEWLINE = "\n";
|
||||
const logstr = listData
|
||||
.map((group) => {
|
||||
const escape = (str: string) => str.replaceAll("\r", "\\r").replaceAll("\n", "\\n");
|
||||
return (
|
||||
group.name +
|
||||
NEWLINE +
|
||||
@ -200,8 +201,9 @@ const WorkflowRunLogs = ({ runId, runStatus }: { runId: string; runStatus: strin
|
||||
.map((record) => {
|
||||
const datetime = dayjs(record.timestamp).format("YYYY-MM-DDTHH:mm:ss.SSSZ");
|
||||
const level = record.level;
|
||||
const message = record.message.trim().replaceAll("\r", "\\r").replaceAll("\n", "\\n");
|
||||
return `[${datetime}] [${level}] ${message}`;
|
||||
const message = record.message;
|
||||
const data = record.data && Object.keys(record.data).length > 0 ? JSON.stringify(record.data) : "";
|
||||
return `[${datetime}] [${level}] ${escape(message)} ${escape(data)}`.trim();
|
||||
})
|
||||
.join(NEWLINE)
|
||||
);
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { memo, useMemo, useRef, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Flex, Typography } from "antd";
|
||||
import { Avatar, Flex, Typography } from "antd";
|
||||
import { produce } from "immer";
|
||||
|
||||
import { notifyProvidersMap } from "@/domain/provider";
|
||||
import { notifyChannelsMap } from "@/domain/settings";
|
||||
import { type WorkflowNodeConfigForNotify, WorkflowNodeType } from "@/domain/workflow";
|
||||
import { useZustandShallowSelector } from "@/hooks";
|
||||
@ -39,9 +40,11 @@ const NotifyNode = ({ node, disabled }: NotifyNodeProps) => {
|
||||
|
||||
const config = (node.config as WorkflowNodeConfigForNotify) ?? {};
|
||||
const channel = notifyChannelsMap.get(config.channel as string);
|
||||
const provider = notifyProvidersMap.get(config.provider);
|
||||
return (
|
||||
<Flex className="size-full overflow-hidden" align="center" gap={8}>
|
||||
<Typography.Text className="flex-1 truncate">{t(channel?.name ?? " ")}</Typography.Text>
|
||||
<Avatar src={provider?.icon} size="small" />
|
||||
<Typography.Text className="flex-1 truncate">{t(channel?.name ?? provider?.name ?? " ")}</Typography.Text>
|
||||
<Typography.Text className="truncate" type="secondary">
|
||||
{config.subject ?? ""}
|
||||
</Typography.Text>
|
||||
|
@ -1,14 +1,19 @@
|
||||
import { forwardRef, memo, useEffect, useImperativeHandle } from "react";
|
||||
import { forwardRef, memo, useEffect, useImperativeHandle, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router";
|
||||
import { RightOutlined as RightOutlinedIcon } from "@ant-design/icons";
|
||||
import { Button, Form, type FormInstance, Input, Select } from "antd";
|
||||
import { PlusOutlined as PlusOutlinedIcon, RightOutlined as RightOutlinedIcon } from "@ant-design/icons";
|
||||
import { Alert, Button, Form, type FormInstance, Input, Select } from "antd";
|
||||
import { createSchemaFieldRule } from "antd-zod";
|
||||
import { z } from "zod";
|
||||
|
||||
import AccessEditModal from "@/components/access/AccessEditModal";
|
||||
import AccessSelect from "@/components/access/AccessSelect";
|
||||
import NotifyProviderSelect from "@/components/provider/NotifyProviderSelect";
|
||||
import { ACCESS_USAGES, accessProvidersMap, notifyProvidersMap } from "@/domain/provider";
|
||||
import { notifyChannelsMap } from "@/domain/settings";
|
||||
import { type WorkflowNodeConfigForNotify } from "@/domain/workflow";
|
||||
import { useAntdForm, useZustandShallowSelector } from "@/hooks";
|
||||
import { useAccessesStore } from "@/stores/access";
|
||||
import { useNotifyChannelsStore } from "@/stores/notify";
|
||||
|
||||
type NotifyNodeConfigFormFieldValues = Partial<WorkflowNodeConfigForNotify>;
|
||||
@ -35,6 +40,8 @@ const NotifyNodeConfigForm = forwardRef<NotifyNodeConfigFormInstance, NotifyNode
|
||||
({ className, style, disabled, initialValues, onValuesChange }, ref) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { accesses } = useAccessesStore(useZustandShallowSelector("accesses"));
|
||||
|
||||
const {
|
||||
channels,
|
||||
loadedAtOnce: channelsLoadedAtOnce,
|
||||
@ -53,7 +60,11 @@ const NotifyNodeConfigForm = forwardRef<NotifyNodeConfigFormInstance, NotifyNode
|
||||
.string({ message: t("workflow_node.notify.form.message.placeholder") })
|
||||
.min(1, t("workflow_node.notify.form.message.placeholder"))
|
||||
.max(1000, t("common.errmsg.string_max", { max: 1000 })),
|
||||
channel: z.string({ message: t("workflow_node.notify.form.channel.placeholder") }).min(1, t("workflow_node.notify.form.channel.placeholder")),
|
||||
channel: z.string().nullish(),
|
||||
provider: z.string({ message: t("workflow_node.notify.form.provider.placeholder") }).nonempty(t("workflow_node.notify.form.provider.placeholder")),
|
||||
providerAccessId: z
|
||||
.string({ message: t("workflow_node.notify.form.provider_access.placeholder") })
|
||||
.nonempty(t("workflow_node.notify.form.provider_access.placeholder")),
|
||||
});
|
||||
const formRule = createSchemaFieldRule(formSchema);
|
||||
const { form: formInst, formProps } = useAntdForm({
|
||||
@ -61,6 +72,49 @@ const NotifyNodeConfigForm = forwardRef<NotifyNodeConfigFormInstance, NotifyNode
|
||||
initialValues: initialValues ?? initFormModel(),
|
||||
});
|
||||
|
||||
const fieldProvider = Form.useWatch<string>("provider", { form: formInst, preserve: true });
|
||||
const fieldProviderAccessId = Form.useWatch<string>("providerAccessId", formInst);
|
||||
|
||||
const [showProvider, setShowProvider] = useState(false);
|
||||
useEffect(() => {
|
||||
// 通常情况下每个授权信息只对应一个消息通知提供商,此时无需显示消息通知提供商字段;
|
||||
// 如果对应多个,则显示。
|
||||
if (fieldProviderAccessId) {
|
||||
const access = accesses.find((e) => e.id === fieldProviderAccessId);
|
||||
const providers = Array.from(notifyProvidersMap.values()).filter((e) => e.provider === access?.provider);
|
||||
setShowProvider(providers.length > 1);
|
||||
} else {
|
||||
setShowProvider(false);
|
||||
}
|
||||
}, [accesses, fieldProviderAccessId]);
|
||||
|
||||
const handleProviderSelect = (value: string) => {
|
||||
if (fieldProvider === value) return;
|
||||
|
||||
// 切换消息通知提供商时联动授权信息
|
||||
if (initialValues?.provider === value) {
|
||||
formInst.setFieldValue("providerAccessId", initialValues?.providerAccessId);
|
||||
onValuesChange?.(formInst.getFieldsValue(true));
|
||||
} else {
|
||||
if (notifyProvidersMap.get(fieldProvider)?.provider !== notifyProvidersMap.get(value)?.provider) {
|
||||
formInst.setFieldValue("providerAccessId", undefined);
|
||||
onValuesChange?.(formInst.getFieldsValue(true));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleProviderAccessSelect = (value: string) => {
|
||||
if (fieldProviderAccessId === value) return;
|
||||
|
||||
// 切换授权信息时联动消息通知提供商
|
||||
const access = accesses.find((access) => access.id === value);
|
||||
const provider = Array.from(notifyProvidersMap.values()).find((provider) => provider.provider === access?.provider);
|
||||
if (fieldProvider !== provider?.type) {
|
||||
formInst.setFieldValue("provider", provider?.type);
|
||||
onValuesChange?.(formInst.getFieldsValue(true));
|
||||
}
|
||||
};
|
||||
|
||||
const handleFormChange = (_: unknown, values: z.infer<typeof formSchema>) => {
|
||||
onValuesChange?.(values as NotifyNodeConfigFormFieldValues);
|
||||
};
|
||||
@ -92,7 +146,7 @@ const NotifyNodeConfigForm = forwardRef<NotifyNodeConfigFormInstance, NotifyNode
|
||||
<Form.Item className="mb-0">
|
||||
<label className="mb-1 block">
|
||||
<div className="flex w-full items-center justify-between gap-4">
|
||||
<div className="max-w-full grow truncate">{t("workflow_node.notify.form.channel.label")}</div>
|
||||
<div className="max-w-full grow truncate line-through">{t("workflow_node.notify.form.channel.label")}</div>
|
||||
<div className="text-right">
|
||||
<Link className="ant-typography" to="/settings/notification" target="_blank">
|
||||
<Button size="small" type="link">
|
||||
@ -116,6 +170,60 @@ const NotifyNodeConfigForm = forwardRef<NotifyNodeConfigFormInstance, NotifyNode
|
||||
/>
|
||||
</Form.Item>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item name="provider" label={t("workflow_node.notify.form.provider.label")} hidden={!showProvider} rules={[formRule]}>
|
||||
<NotifyProviderSelect
|
||||
disabled={!showProvider}
|
||||
filter={(record) => {
|
||||
if (fieldProviderAccessId) {
|
||||
return accesses.find((e) => e.id === fieldProviderAccessId)?.provider === record.provider;
|
||||
}
|
||||
|
||||
return true;
|
||||
}}
|
||||
placeholder={t("workflow_node.notify.form.provider.placeholder")}
|
||||
showSearch
|
||||
onSelect={handleProviderSelect}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item className="mb-0">
|
||||
<label className="mb-1 block">
|
||||
<div className="flex w-full items-center justify-between gap-4">
|
||||
<div className="max-w-full grow truncate">
|
||||
<span>{t("workflow_node.notify.form.provider_access.label")}</span>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<AccessEditModal
|
||||
range="notify-only"
|
||||
scene="add"
|
||||
trigger={
|
||||
<Button size="small" type="link">
|
||||
{t("workflow_node.notify.form.provider_access.button")}
|
||||
<PlusOutlinedIcon className="text-xs" />
|
||||
</Button>
|
||||
}
|
||||
afterSubmit={(record) => {
|
||||
const provider = accessProvidersMap.get(record.provider);
|
||||
if (provider?.usages?.includes(ACCESS_USAGES.NOTIFICATION)) {
|
||||
formInst.setFieldValue("providerAccessId", record.id);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
<Form.Item name="providerAccessId" rules={[formRule]}>
|
||||
<AccessSelect
|
||||
filter={(record) => {
|
||||
const provider = accessProvidersMap.get(record.provider);
|
||||
return !!provider?.usages?.includes(ACCESS_USAGES.NOTIFICATION);
|
||||
}}
|
||||
placeholder={t("workflow_node.notify.form.provider_access.placeholder")}
|
||||
onChange={handleProviderAccessSelect}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
|
@ -201,9 +201,9 @@ export const applyCAProvidersMap: Map<ApplyCAProvider["type"] | string, ApplyCAP
|
||||
|
||||
// #region ApplyDNSProvider
|
||||
/*
|
||||
注意:如果追加新的常量值,请保持以 ASCII 排序。
|
||||
NOTICE: If you add new constant, please keep ASCII order.
|
||||
*/
|
||||
注意:如果追加新的常量值,请保持以 ASCII 排序。
|
||||
NOTICE: If you add new constant, please keep ASCII order.
|
||||
*/
|
||||
export const APPLY_DNS_PROVIDERS = Object.freeze({
|
||||
ACMEHTTPREQ: `${ACCESS_PROVIDERS.ACMEHTTPREQ}`,
|
||||
ALIYUN: `${ACCESS_PROVIDERS.ALIYUN}`, // 兼容旧值,等同于 `ALIYUN_DNS`
|
||||
@ -255,9 +255,9 @@ export type ApplyDNSProvider = {
|
||||
|
||||
export const applyDNSProvidersMap: Map<ApplyDNSProvider["type"] | string, ApplyDNSProvider> = new Map(
|
||||
/*
|
||||
注意:此处的顺序决定显示在前端的顺序。
|
||||
NOTICE: The following order determines the order displayed at the frontend.
|
||||
*/
|
||||
注意:此处的顺序决定显示在前端的顺序。
|
||||
NOTICE: The following order determines the order displayed at the frontend.
|
||||
*/
|
||||
[
|
||||
[APPLY_DNS_PROVIDERS.ALIYUN_DNS, "provider.aliyun.dns"],
|
||||
[APPLY_DNS_PROVIDERS.TENCENTCLOUD_DNS, "provider.tencentcloud.dns"],
|
||||
@ -302,9 +302,9 @@ export const applyDNSProvidersMap: Map<ApplyDNSProvider["type"] | string, ApplyD
|
||||
|
||||
// #region DeployProvider
|
||||
/*
|
||||
注意:如果追加新的常量值,请保持以 ASCII 排序。
|
||||
NOTICE: If you add new constant, please keep ASCII order.
|
||||
*/
|
||||
注意:如果追加新的常量值,请保持以 ASCII 排序。
|
||||
NOTICE: If you add new constant, please keep ASCII order.
|
||||
*/
|
||||
export const DEPLOY_PROVIDERS = Object.freeze({
|
||||
["1PANEL_CONSOLE"]: `${ACCESS_PROVIDERS["1PANEL"]}-console`,
|
||||
["1PANEL_SITE"]: `${ACCESS_PROVIDERS["1PANEL"]}-site`,
|
||||
@ -500,3 +500,38 @@ export const deployProvidersMap: Map<DeployProvider["type"] | string, DeployProv
|
||||
])
|
||||
);
|
||||
// #endregion
|
||||
|
||||
// #region NotifyProvider
|
||||
/*
|
||||
注意:如果追加新的常量值,请保持以 ASCII 排序。
|
||||
NOTICE: If you add new constant, please keep ASCII order.
|
||||
*/
|
||||
export const NOTIFY_PROVIDERS = Object.freeze({
|
||||
WEBHOOK: `${ACCESS_PROVIDERS.WEBHOOK}`,
|
||||
} as const);
|
||||
|
||||
export type NotifyProviderType = (typeof APPLY_CA_PROVIDERS)[keyof typeof APPLY_CA_PROVIDERS];
|
||||
|
||||
export type NotifyProvider = {
|
||||
type: NotifyProviderType;
|
||||
name: string;
|
||||
icon: string;
|
||||
provider: AccessProviderType;
|
||||
};
|
||||
|
||||
export const notifyProvidersMap: Map<NotifyProvider["type"] | string, NotifyProvider> = new Map(
|
||||
/*
|
||||
注意:此处的顺序决定显示在前端的顺序。
|
||||
NOTICE: The following order determines the order displayed at the frontend.
|
||||
*/
|
||||
[[NOTIFY_PROVIDERS.WEBHOOK]].map(([type]) => [
|
||||
type,
|
||||
{
|
||||
type: type as ApplyCAProviderType,
|
||||
name: accessProvidersMap.get(type.split("-")[0])!.name,
|
||||
icon: accessProvidersMap.get(type.split("-")[0])!.icon,
|
||||
provider: type.split("-")[0] as AccessProviderType,
|
||||
},
|
||||
])
|
||||
);
|
||||
// #endregion
|
||||
|
@ -3,6 +3,9 @@ import { type ApplyCAProviderType } from "./provider";
|
||||
export const SETTINGS_NAMES = Object.freeze({
|
||||
EMAILS: "emails",
|
||||
NOTIFY_TEMPLATES: "notifyTemplates",
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
NOTIFY_CHANNELS: "notifyChannels",
|
||||
SSL_PROVIDER: "sslProvider",
|
||||
PERSISTENCE: "persistence",
|
||||
@ -38,6 +41,9 @@ export const defaultNotifyTemplate: NotifyTemplate = {
|
||||
// #endregion
|
||||
|
||||
// #region Settings: NotifyChannels
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export const NOTIFY_CHANNELS = Object.freeze({
|
||||
BARK: "bark",
|
||||
DINGTALK: "dingtalk",
|
||||
@ -53,8 +59,14 @@ export const NOTIFY_CHANNELS = Object.freeze({
|
||||
WECOM: "wecom",
|
||||
} as const);
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export type NotifyChannels = (typeof NOTIFY_CHANNELS)[keyof typeof NOTIFY_CHANNELS];
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export type NotifyChannelsSettingsContent = {
|
||||
/*
|
||||
注意:如果追加新的类型,请保持以 ASCII 排序。
|
||||
@ -116,7 +128,7 @@ export type MattermostNotifyChannelConfig = {
|
||||
username: string;
|
||||
password: string;
|
||||
enabled?: boolean;
|
||||
}
|
||||
};
|
||||
|
||||
export type PushoverNotifyChannelConfig = {
|
||||
token: string;
|
||||
@ -155,6 +167,9 @@ export type NotifyChannel = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export const notifyChannelsMap: Map<NotifyChannel["type"], NotifyChannel> = new Map(
|
||||
[
|
||||
[NOTIFY_CHANNELS.EMAIL, "common.notifier.email"],
|
||||
|
@ -154,9 +154,15 @@ export type WorkflowNodeConfigForDeploy = {
|
||||
};
|
||||
|
||||
export type WorkflowNodeConfigForNotify = {
|
||||
channel: string;
|
||||
subject: string;
|
||||
message: string;
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
channel?: string;
|
||||
provider: string;
|
||||
providerAccessId: string;
|
||||
providerConfig?: Record<string, unknown>;
|
||||
};
|
||||
|
||||
export type WorkflowNodeConfigForBranch = never;
|
||||
|
@ -712,9 +712,14 @@
|
||||
"workflow_node.notify.form.subject.placeholder": "Please enter subject",
|
||||
"workflow_node.notify.form.message.label": "Message",
|
||||
"workflow_node.notify.form.message.placeholder": "Please enter message",
|
||||
"workflow_node.notify.form.channel.label": "Channel",
|
||||
"workflow_node.notify.form.channel.label": "Channel (Deprecated)",
|
||||
"workflow_node.notify.form.channel.placeholder": "Please select channel",
|
||||
"workflow_node.notify.form.channel.button": "Configure",
|
||||
"workflow_node.notify.form.provider.label": "Notification channel",
|
||||
"workflow_node.notify.form.provider.placeholder": "Please select notification channel",
|
||||
"workflow_node.notify.form.provider_access.label": "Notification provider authorization",
|
||||
"workflow_node.notify.form.provider_access.placeholder": "Please select an authorization of notification provider",
|
||||
"workflow_node.notify.form.provider_access.button": "Create",
|
||||
|
||||
"workflow_node.end.label": "End",
|
||||
|
||||
|
@ -711,9 +711,14 @@
|
||||
"workflow_node.notify.form.subject.placeholder": "请输入通知主题",
|
||||
"workflow_node.notify.form.message.label": "通知内容",
|
||||
"workflow_node.notify.form.message.placeholder": "请输入通知内容",
|
||||
"workflow_node.notify.form.channel.label": "通知渠道",
|
||||
"workflow_node.notify.form.channel.label": "通知渠道(已废弃,请使用「通知渠道授权」字段)",
|
||||
"workflow_node.notify.form.channel.placeholder": "请选择通知渠道",
|
||||
"workflow_node.notify.form.channel.button": "去配置",
|
||||
"workflow_node.notify.form.channel.button": "设置",
|
||||
"workflow_node.notify.form.provider.label": "通知渠道",
|
||||
"workflow_node.notify.form.provider.placeholder": "请选择通知渠道",
|
||||
"workflow_node.notify.form.provider_access.label": "通知渠道授权",
|
||||
"workflow_node.notify.form.provider_access.placeholder": "请选择通知渠道授权",
|
||||
"workflow_node.notify.form.provider_access.button": "新建",
|
||||
|
||||
"workflow_node.end.label": "结束",
|
||||
|
||||
|
@ -185,10 +185,12 @@ const AccessList = () => {
|
||||
|
||||
const handleTabChange = (key: string) => {
|
||||
setFilters((prev) => ({ ...prev, range: key }));
|
||||
setPage(1);
|
||||
};
|
||||
|
||||
const handleSearch = (value: string) => {
|
||||
setFilters((prev) => ({ ...prev, keyword: value }));
|
||||
setPage(1);
|
||||
};
|
||||
|
||||
const handleReloadClick = () => {
|
||||
@ -251,10 +253,10 @@ const AccessList = () => {
|
||||
key: "ca-only",
|
||||
label: t("access.props.range.ca_only"),
|
||||
},
|
||||
// {
|
||||
// key: "notify-only",
|
||||
// label: t("access.props.range.notify_only"),
|
||||
// },
|
||||
{
|
||||
key: "notify-only",
|
||||
label: t("access.props.range.notify_only"),
|
||||
},
|
||||
]}
|
||||
activeTabKey={filters["range"] as string}
|
||||
onTabChange={(key) => handleTabChange(key)}
|
||||
|
@ -251,6 +251,7 @@ const CertificateList = () => {
|
||||
|
||||
const handleSearch = (value: string) => {
|
||||
setFilters((prev) => ({ ...prev, keyword: value.trim() }));
|
||||
setPage(1);
|
||||
};
|
||||
|
||||
const handleReloadClick = () => {
|
||||
|
@ -1,11 +1,14 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Card, Divider } from "antd";
|
||||
import { Alert, Card, Divider } from "antd";
|
||||
|
||||
import NotifyChannels from "@/components/notification/NotifyChannels";
|
||||
import NotifyTemplate from "@/components/notification/NotifyTemplate";
|
||||
import { useZustandShallowSelector } from "@/hooks";
|
||||
import { useNotifyChannelsStore } from "@/stores/notify";
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
const SettingsNotification = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@ -22,6 +25,7 @@ const SettingsNotification = () => {
|
||||
<Divider />
|
||||
|
||||
<Card className="shadow" styles={{ body: loadedAtOnce ? { padding: 0 } : {} }} title={t("settings.notification.channels.card.title")}>
|
||||
<Alert type="warning" banner message="本页面相关功能即将在后续版本中废弃,请使用「授权管理」页面来管理通知渠道。" />
|
||||
<NotifyChannels classNames={{ form: "md:max-w-[40rem]" }} />
|
||||
</Card>
|
||||
</div>
|
||||
|
@ -281,6 +281,7 @@ const WorkflowList = () => {
|
||||
|
||||
const handleSearch = (value: string) => {
|
||||
setFilters((prev) => ({ ...prev, keyword: value.trim() }));
|
||||
setPage(1);
|
||||
};
|
||||
|
||||
const handleCreateClick = () => {
|
||||
|
@ -4,6 +4,9 @@ import { create } from "zustand";
|
||||
import { type NotifyChannelsSettingsContent, SETTINGS_NAMES, type SettingsModel } from "@/domain/settings";
|
||||
import { get as getSettings, save as saveSettings } from "@/repository/settings";
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export interface NotifyChannelsState {
|
||||
channels: NotifyChannelsSettingsContent;
|
||||
loading: boolean;
|
||||
@ -14,6 +17,9 @@ export interface NotifyChannelsState {
|
||||
setChannels: (channels: NotifyChannelsSettingsContent) => Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
export const useNotifyChannelsStore = create<NotifyChannelsState>((set, get) => {
|
||||
let fetcher: Promise<SettingsModel<NotifyChannelsSettingsContent>> | null = null; // 防止多次重复请求
|
||||
let settings: SettingsModel<NotifyChannelsSettingsContent>; // 记录当前设置的其他字段,保存回数据库时用
|
||||
|
Loading…
x
Reference in New Issue
Block a user