feat: add ExtractCertificatesFromPEM util func

This commit is contained in:
Fu Diwei 2025-02-06 13:11:40 +08:00
parent bc29cce645
commit 5f5c835533
7 changed files with 125 additions and 97 deletions

View File

@ -35,8 +35,8 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
case domain.ApplyDNSProviderTypeACMEHttpReq: case domain.ApplyDNSProviderTypeACMEHttpReq:
{ {
access := domain.AccessConfigForACMEHttpReq{} access := domain.AccessConfigForACMEHttpReq{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerACMEHttpReq.NewChallengeProvider(&providerACMEHttpReq.ACMEHttpReqApplicantConfig{ applicant, err := providerACMEHttpReq.NewChallengeProvider(&providerACMEHttpReq.ACMEHttpReqApplicantConfig{
@ -52,8 +52,8 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
case domain.ApplyDNSProviderTypeAliyun, domain.ApplyDNSProviderTypeAliyunDNS: case domain.ApplyDNSProviderTypeAliyun, domain.ApplyDNSProviderTypeAliyunDNS:
{ {
access := domain.AccessConfigForAliyun{} access := domain.AccessConfigForAliyun{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerAliyun.NewChallengeProvider(&providerAliyun.AliyunApplicantConfig{ applicant, err := providerAliyun.NewChallengeProvider(&providerAliyun.AliyunApplicantConfig{
@ -68,8 +68,8 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
case domain.ApplyDNSProviderTypeAWS, domain.ApplyDNSProviderTypeAWSRoute53: case domain.ApplyDNSProviderTypeAWS, domain.ApplyDNSProviderTypeAWSRoute53:
{ {
access := domain.AccessConfigForAWS{} access := domain.AccessConfigForAWS{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerAWSRoute53.NewChallengeProvider(&providerAWSRoute53.AWSRoute53ApplicantConfig{ applicant, err := providerAWSRoute53.NewChallengeProvider(&providerAWSRoute53.AWSRoute53ApplicantConfig{
@ -86,8 +86,8 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
case domain.ApplyDNSProviderTypeAzureDNS: case domain.ApplyDNSProviderTypeAzureDNS:
{ {
access := domain.AccessConfigForAzure{} access := domain.AccessConfigForAzure{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerAzureDNS.NewChallengeProvider(&providerAzureDNS.AzureDNSApplicantConfig{ applicant, err := providerAzureDNS.NewChallengeProvider(&providerAzureDNS.AzureDNSApplicantConfig{
@ -104,8 +104,8 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
case domain.ApplyDNSProviderTypeCloudflare: case domain.ApplyDNSProviderTypeCloudflare:
{ {
access := domain.AccessConfigForCloudflare{} access := domain.AccessConfigForCloudflare{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerCloudflare.NewChallengeProvider(&providerCloudflare.CloudflareApplicantConfig{ applicant, err := providerCloudflare.NewChallengeProvider(&providerCloudflare.CloudflareApplicantConfig{
@ -119,8 +119,8 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
case domain.ApplyDNSProviderTypeClouDNS: case domain.ApplyDNSProviderTypeClouDNS:
{ {
access := domain.AccessConfigForClouDNS{} access := domain.AccessConfigForClouDNS{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerClouDNS.NewChallengeProvider(&providerClouDNS.ClouDNSApplicantConfig{ applicant, err := providerClouDNS.NewChallengeProvider(&providerClouDNS.ClouDNSApplicantConfig{
@ -135,8 +135,8 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
case domain.ApplyDNSProviderTypeGname: case domain.ApplyDNSProviderTypeGname:
{ {
access := domain.AccessConfigForGname{} access := domain.AccessConfigForGname{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerGname.NewChallengeProvider(&providerGname.GnameApplicantConfig{ applicant, err := providerGname.NewChallengeProvider(&providerGname.GnameApplicantConfig{
@ -151,8 +151,8 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
case domain.ApplyDNSProviderTypeGoDaddy: case domain.ApplyDNSProviderTypeGoDaddy:
{ {
access := domain.AccessConfigForGoDaddy{} access := domain.AccessConfigForGoDaddy{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerGoDaddy.NewChallengeProvider(&providerGoDaddy.GoDaddyApplicantConfig{ applicant, err := providerGoDaddy.NewChallengeProvider(&providerGoDaddy.GoDaddyApplicantConfig{
@ -167,8 +167,8 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
case domain.ApplyDNSProviderTypeHuaweiCloud, domain.ApplyDNSProviderTypeHuaweiCloudDNS: case domain.ApplyDNSProviderTypeHuaweiCloud, domain.ApplyDNSProviderTypeHuaweiCloudDNS:
{ {
access := domain.AccessConfigForHuaweiCloud{} access := domain.AccessConfigForHuaweiCloud{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerHuaweiCloud.NewChallengeProvider(&providerHuaweiCloud.HuaweiCloudApplicantConfig{ applicant, err := providerHuaweiCloud.NewChallengeProvider(&providerHuaweiCloud.HuaweiCloudApplicantConfig{
@ -184,8 +184,8 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
case domain.ApplyDNSProviderTypeNameDotCom: case domain.ApplyDNSProviderTypeNameDotCom:
{ {
access := domain.AccessConfigForNameDotCom{} access := domain.AccessConfigForNameDotCom{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerNameDotCom.NewChallengeProvider(&providerNameDotCom.NameDotComApplicantConfig{ applicant, err := providerNameDotCom.NewChallengeProvider(&providerNameDotCom.NameDotComApplicantConfig{
@ -200,8 +200,8 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
case domain.ApplyDNSProviderTypeNameSilo: case domain.ApplyDNSProviderTypeNameSilo:
{ {
access := domain.AccessConfigForNameSilo{} access := domain.AccessConfigForNameSilo{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerNameSilo.NewChallengeProvider(&providerNameSilo.NameSiloApplicantConfig{ applicant, err := providerNameSilo.NewChallengeProvider(&providerNameSilo.NameSiloApplicantConfig{
@ -215,8 +215,8 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
case domain.ApplyDNSProviderTypeNS1: case domain.ApplyDNSProviderTypeNS1:
{ {
access := domain.AccessConfigForNS1{} access := domain.AccessConfigForNS1{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerNS1.NewChallengeProvider(&providerNS1.NS1ApplicantConfig{ applicant, err := providerNS1.NewChallengeProvider(&providerNS1.NS1ApplicantConfig{
@ -230,8 +230,8 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
case domain.ApplyDNSProviderTypePowerDNS: case domain.ApplyDNSProviderTypePowerDNS:
{ {
access := domain.AccessConfigForPowerDNS{} access := domain.AccessConfigForPowerDNS{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerPowerDNS.NewChallengeProvider(&providerPowerDNS.PowerDNSApplicantConfig{ applicant, err := providerPowerDNS.NewChallengeProvider(&providerPowerDNS.PowerDNSApplicantConfig{
@ -246,8 +246,8 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
case domain.ApplyDNSProviderTypeRainYun: case domain.ApplyDNSProviderTypeRainYun:
{ {
access := domain.AccessConfigForRainYun{} access := domain.AccessConfigForRainYun{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerRainYun.NewChallengeProvider(&providerRainYun.RainYunApplicantConfig{ applicant, err := providerRainYun.NewChallengeProvider(&providerRainYun.RainYunApplicantConfig{
@ -261,8 +261,8 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
case domain.ApplyDNSProviderTypeTencentCloud, domain.ApplyDNSProviderTypeTencentCloudDNS: case domain.ApplyDNSProviderTypeTencentCloud, domain.ApplyDNSProviderTypeTencentCloudDNS:
{ {
access := domain.AccessConfigForTencentCloud{} access := domain.AccessConfigForTencentCloud{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerTencentCloud.NewChallengeProvider(&providerTencentCloud.TencentCloudApplicantConfig{ applicant, err := providerTencentCloud.NewChallengeProvider(&providerTencentCloud.TencentCloudApplicantConfig{
@ -277,8 +277,8 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
case domain.ApplyDNSProviderTypeVolcEngine, domain.ApplyDNSProviderTypeVolcEngineDNS: case domain.ApplyDNSProviderTypeVolcEngine, domain.ApplyDNSProviderTypeVolcEngineDNS:
{ {
access := domain.AccessConfigForVolcEngine{} access := domain.AccessConfigForVolcEngine{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerVolcEngine.NewChallengeProvider(&providerVolcEngine.VolcEngineApplicantConfig{ applicant, err := providerVolcEngine.NewChallengeProvider(&providerVolcEngine.VolcEngineApplicantConfig{
@ -293,8 +293,8 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
case domain.ApplyDNSProviderTypeWestcn: case domain.ApplyDNSProviderTypeWestcn:
{ {
access := domain.AccessConfigForWestcn{} access := domain.AccessConfigForWestcn{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerWestcn.NewChallengeProvider(&providerWestcn.WestcnApplicantConfig{ applicant, err := providerWestcn.NewChallengeProvider(&providerWestcn.WestcnApplicantConfig{

View File

@ -54,8 +54,8 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
case domain.DeployProviderTypeAliyunALB, domain.DeployProviderTypeAliyunCDN, domain.DeployProviderTypeAliyunCLB, domain.DeployProviderTypeAliyunDCDN, domain.DeployProviderTypeAliyunLive, domain.DeployProviderTypeAliyunNLB, domain.DeployProviderTypeAliyunOSS, domain.DeployProviderTypeAliyunWAF: case domain.DeployProviderTypeAliyunALB, domain.DeployProviderTypeAliyunCDN, domain.DeployProviderTypeAliyunCLB, domain.DeployProviderTypeAliyunDCDN, domain.DeployProviderTypeAliyunLive, domain.DeployProviderTypeAliyunNLB, domain.DeployProviderTypeAliyunOSS, domain.DeployProviderTypeAliyunWAF:
{ {
access := domain.AccessConfigForAliyun{} access := domain.AccessConfigForAliyun{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
switch options.Provider { switch options.Provider {
@ -146,8 +146,8 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
case domain.DeployProviderTypeAWSCloudFront: case domain.DeployProviderTypeAWSCloudFront:
{ {
access := domain.AccessConfigForAWS{} access := domain.AccessConfigForAWS{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
switch options.Provider { switch options.Provider {
@ -168,8 +168,8 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
case domain.DeployProviderTypeBaiduCloudCDN: case domain.DeployProviderTypeBaiduCloudCDN:
{ {
access := domain.AccessConfigForBaiduCloud{} access := domain.AccessConfigForBaiduCloud{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
switch options.Provider { switch options.Provider {
@ -189,8 +189,8 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
case domain.DeployProviderTypeBytePlusCDN: case domain.DeployProviderTypeBytePlusCDN:
{ {
access := domain.AccessConfigForBytePlus{} access := domain.AccessConfigForBytePlus{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
switch options.Provider { switch options.Provider {
@ -210,8 +210,8 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
case domain.DeployProviderTypeDogeCloudCDN: case domain.DeployProviderTypeDogeCloudCDN:
{ {
access := domain.AccessConfigForDogeCloud{} access := domain.AccessConfigForDogeCloud{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
deployer, err := providerDogeCDN.NewWithLogger(&providerDogeCDN.DogeCloudCDNDeployerConfig{ deployer, err := providerDogeCDN.NewWithLogger(&providerDogeCDN.DogeCloudCDNDeployerConfig{
@ -225,8 +225,8 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
case domain.DeployProviderTypeEdgioApplications: case domain.DeployProviderTypeEdgioApplications:
{ {
access := domain.AccessConfigForEdgio{} access := domain.AccessConfigForEdgio{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
deployer, err := providerEdgioApplications.NewWithLogger(&providerEdgioApplications.EdgioApplicationsDeployerConfig{ deployer, err := providerEdgioApplications.NewWithLogger(&providerEdgioApplications.EdgioApplicationsDeployerConfig{
@ -240,8 +240,8 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
case domain.DeployProviderTypeHuaweiCloudCDN, domain.DeployProviderTypeHuaweiCloudELB: case domain.DeployProviderTypeHuaweiCloudCDN, domain.DeployProviderTypeHuaweiCloudELB:
{ {
access := domain.AccessConfigForHuaweiCloud{} access := domain.AccessConfigForHuaweiCloud{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
switch options.Provider { switch options.Provider {
@ -291,8 +291,8 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
case domain.DeployProviderTypeKubernetesSecret: case domain.DeployProviderTypeKubernetesSecret:
{ {
access := domain.AccessConfigForKubernetes{} access := domain.AccessConfigForKubernetes{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
deployer, err := providerK8sSecret.NewWithLogger(&providerK8sSecret.K8sSecretDeployerConfig{ deployer, err := providerK8sSecret.NewWithLogger(&providerK8sSecret.K8sSecretDeployerConfig{
@ -309,8 +309,8 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
case domain.DeployProviderTypeQiniuCDN, domain.DeployProviderTypeQiniuPili: case domain.DeployProviderTypeQiniuCDN, domain.DeployProviderTypeQiniuPili:
{ {
access := domain.AccessConfigForQiniu{} access := domain.AccessConfigForQiniu{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
switch options.Provider { switch options.Provider {
@ -339,8 +339,8 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
case domain.DeployProviderTypeSSH: case domain.DeployProviderTypeSSH:
{ {
access := domain.AccessConfigForSSH{} access := domain.AccessConfigForSSH{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
deployer, err := providerSSH.NewWithLogger(&providerSSH.SshDeployerConfig{ deployer, err := providerSSH.NewWithLogger(&providerSSH.SshDeployerConfig{
@ -367,8 +367,8 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
case domain.DeployProviderTypeTencentCloudCDN, domain.DeployProviderTypeTencentCloudCLB, domain.DeployProviderTypeTencentCloudCOS, domain.DeployProviderTypeTencentCloudCSS, domain.DeployProviderTypeTencentCloudECDN, domain.DeployProviderTypeTencentCloudEO: case domain.DeployProviderTypeTencentCloudCDN, domain.DeployProviderTypeTencentCloudCLB, domain.DeployProviderTypeTencentCloudCOS, domain.DeployProviderTypeTencentCloudCSS, domain.DeployProviderTypeTencentCloudECDN, domain.DeployProviderTypeTencentCloudEO:
{ {
access := domain.AccessConfigForTencentCloud{} access := domain.AccessConfigForTencentCloud{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
switch options.Provider { switch options.Provider {
@ -435,8 +435,8 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
case domain.DeployProviderTypeUCloudUCDN, domain.DeployProviderTypeUCloudUS3: case domain.DeployProviderTypeUCloudUCDN, domain.DeployProviderTypeUCloudUS3:
{ {
access := domain.AccessConfigForUCloud{} access := domain.AccessConfigForUCloud{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
switch options.Provider { switch options.Provider {
@ -468,8 +468,8 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
case domain.DeployProviderTypeVolcEngineCDN, domain.DeployProviderTypeVolcEngineCLB, domain.DeployProviderTypeVolcEngineDCDN, domain.DeployProviderTypeVolcEngineLive, domain.DeployProviderTypeVolcEngineTOS: case domain.DeployProviderTypeVolcEngineCDN, domain.DeployProviderTypeVolcEngineCLB, domain.DeployProviderTypeVolcEngineDCDN, domain.DeployProviderTypeVolcEngineLive, domain.DeployProviderTypeVolcEngineTOS:
{ {
access := domain.AccessConfigForVolcEngine{} access := domain.AccessConfigForVolcEngine{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
switch options.Provider { switch options.Provider {
@ -525,8 +525,8 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
case domain.DeployProviderTypeWebhook: case domain.DeployProviderTypeWebhook:
{ {
access := domain.AccessConfigForWebhook{} access := domain.AccessConfigForWebhook{}
if err := maps.Decode(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to decode provider access config: %w", err) return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
deployer, err := providerWebhook.NewWithLogger(&providerWebhook.WebhookDeployerConfig{ deployer, err := providerWebhook.NewWithLogger(&providerWebhook.WebhookDeployerConfig{

View File

@ -2,13 +2,13 @@
import ( import (
"context" "context"
"encoding/pem"
"errors" "errors"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/logger"
"github.com/usual2970/certimate/internal/pkg/utils/certs"
edgsdk "github.com/usual2970/certimate/internal/pkg/vendors/edgio-sdk/applications/v7" edgsdk "github.com/usual2970/certimate/internal/pkg/vendors/edgio-sdk/applications/v7"
edgsdkDtos "github.com/usual2970/certimate/internal/pkg/vendors/edgio-sdk/applications/v7/dtos" edgsdkDtos "github.com/usual2970/certimate/internal/pkg/vendors/edgio-sdk/applications/v7/dtos"
) )
@ -57,7 +57,10 @@ func NewWithLogger(config *EdgioApplicationsDeployerConfig, logger logger.Logger
func (d *EdgioApplicationsDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *EdgioApplicationsDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 提取 Edgio 所需的服务端证书和中间证书内容 // 提取 Edgio 所需的服务端证书和中间证书内容
privateCertPem, intermediateCertPem := extractCertChains(certPem) privateCertPem, intermediateCertPem, err := certs.ExtractCertificatesFromPEM(certPem)
if err != nil {
return nil, err
}
// 上传 TLS 证书 // 上传 TLS 证书
// REF: https://docs.edg.io/rest_api/#tag/tls-certs/operation/postConfigV01TlsCerts // REF: https://docs.edg.io/rest_api/#tag/tls-certs/operation/postConfigV01TlsCerts
@ -81,32 +84,3 @@ func createSdkClient(clientId, clientSecret string) (*edgsdk.EdgioClient, error)
client := edgsdk.NewEdgioClient(clientId, clientSecret, "", "") client := edgsdk.NewEdgioClient(clientId, clientSecret, "", "")
return client, nil return client, nil
} }
func extractCertChains(certPem string) (primaryCertPem string, intermediateCertPem string) {
pemBlocks := make([]*pem.Block, 0)
pemData := []byte(certPem)
for {
block, rest := pem.Decode(pemData)
if block == nil {
break
}
pemBlocks = append(pemBlocks, block)
pemData = rest
}
primaryCertPem = ""
intermediateCertPem = ""
if len(pemBlocks) > 0 {
primaryCertPem = string(pem.EncodeToMemory(pemBlocks[0]))
}
if len(pemBlocks) > 1 {
for i := 1; i < len(pemBlocks); i++ {
intermediateCertPem += string(pem.EncodeToMemory(pemBlocks[i]))
}
}
return primaryCertPem, intermediateCertPem
}

View File

@ -0,0 +1,48 @@
package certs
import (
"encoding/pem"
"errors"
)
// 从 PEM 编码的证书字符串解析并提取服务器证书和中间证书。
//
// 入参:
// - certPem: 证书 PEM 内容。
//
// 出参:
// - serverCertPem: 服务器证书的 PEM 内容。
// - interCertPem: 中间证书的 PEM 内容。
// - err: 错误。
func ExtractCertificatesFromPEM(certPem string) (serverCertPem string, interCertPem string, err error) {
pemBlocks := make([]*pem.Block, 0)
pemData := []byte(certPem)
for {
block, rest := pem.Decode(pemData)
if block == nil || block.Type != "CERTIFICATE" {
break
}
pemBlocks = append(pemBlocks, block)
pemData = rest
}
serverCertPem = ""
interCertPem = ""
if len(pemBlocks) == 0 {
return "", "", errors.New("failed to decode PEM block")
}
if len(pemBlocks) > 0 {
serverCertPem = string(pem.EncodeToMemory(pemBlocks[0]))
}
if len(pemBlocks) > 1 {
for i := 1; i < len(pemBlocks); i++ {
interCertPem += string(pem.EncodeToMemory(pemBlocks[i]))
}
}
return serverCertPem, interCertPem, nil
}

View File

@ -13,6 +13,7 @@ import (
) )
// 从 PEM 编码的证书字符串解析并返回一个 x509.Certificate 对象。 // 从 PEM 编码的证书字符串解析并返回一个 x509.Certificate 对象。
// PEM 内容可能是包含多张证书的证书链,但只返回第一个证书(即服务器证书)。
// //
// 入参: // 入参:
// - certPem: 证书 PEM 内容。 // - certPem: 证书 PEM 内容。

View File

@ -183,7 +183,7 @@ func GetValueOrDefaultAsBool(dict map[string]any, key string, defaultValue bool)
return defaultValue return defaultValue
} }
// 将字典解码为指定类型的结构体。 // 将字典填充到指定类型的结构体。
// 与 [json.Unmarshal] 类似,但传入的是一个 [map[string]interface{}] 对象而非 JSON 格式的字符串。 // 与 [json.Unmarshal] 类似,但传入的是一个 [map[string]interface{}] 对象而非 JSON 格式的字符串。
// //
// 入参: // 入参:
@ -191,8 +191,8 @@ func GetValueOrDefaultAsBool(dict map[string]any, key string, defaultValue bool)
// - output: 结构体指针。 // - output: 结构体指针。
// //
// 出参: // 出参:
// - 错误信息。如果解码失败,则返回错误信息。 // - 错误信息。如果填充失败,则返回错误信息。
func Decode(dict map[string]any, output any) error { func Populate(dict map[string]any, output any) error {
config := &mapstructure.DecoderConfig{ config := &mapstructure.DecoderConfig{
Metadata: nil, Metadata: nil,
Result: output, Result: output,
@ -207,3 +207,8 @@ func Decode(dict map[string]any, output any) error {
return decoder.Decode(dict) return decoder.Decode(dict)
} }
// Deprecated: Use [Populate] instead.
func Decode(dict map[string]any, output any) error {
return Populate(dict, output)
}

View File

@ -150,7 +150,7 @@ func (c *GnameClient) sendRequestWithResult(path string, params map[string]any,
if err := json.Unmarshal(resp.Body(), &jsonResp); err != nil { if err := json.Unmarshal(resp.Body(), &jsonResp); err != nil {
return fmt.Errorf("failed to parse response: %w", err) return fmt.Errorf("failed to parse response: %w", err)
} }
if err := maps.Decode(jsonResp, &result); err != nil { if err := maps.Populate(jsonResp, &result); err != nil {
return fmt.Errorf("failed to parse response: %w", err) return fmt.Errorf("failed to parse response: %w", err)
} }