From 299a722aa9334d04479b71f68c94c0e79d264b5f Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Tue, 17 Jun 2025 10:39:39 +0800 Subject: [PATCH] refactor: re-impl sdk3rd --- .../lego-providers/azure-dns/azure-dns.go | 4 +- .../lego-providers/dnsla/internal/lego.go | 39 +-- .../lego-providers/gname/internal/lego.go | 46 ++-- .../ucloud-udnr/internal/lego.go | 1 + .../1panel-console/1panel_console.go | 105 +++++--- .../providers/1panel-site/1panel_site.go | 206 ++++++++++----- .../core/deployer/providers/apisix/apisix.go | 18 +- .../azure-keyvault/azure_keyvault.go | 8 +- .../providers/baishan-cdn/baishan_cdn.go | 50 ++-- .../baotapanel-console/baotapanel_console.go | 14 +- .../baotapanel-site/baotapanel_site.go | 13 +- .../baotawaf-console/baotawaf_console.go | 33 +-- .../providers/baotawaf-site/baotawaf_site.go | 29 +-- .../deployer/providers/bunny-cdn/bunny_cdn.go | 20 +- .../deployer/providers/cachefly/cachefly.go | 21 +- .../core/deployer/providers/cdnfly/cdnfly.go | 73 +++--- .../providers/dogecloud-cdn/dogecloud_cdn.go | 21 +- .../deployer/providers/flexcdn/flexcdn.go | 21 +- .../deployer/providers/gcore-cdn/gcore_cdn.go | 2 +- .../core/deployer/providers/goedge/goedge.go | 21 +- .../core/deployer/providers/lecdn/lecdn.go | 105 ++++---- .../providers/netlify-site/netlify_site.go | 7 +- .../netlify-site/netlify_site_test.go | 4 +- .../deployer/providers/qiniu-cdn/qiniu_cdn.go | 4 +- .../providers/rainyun-rcdn/rainyun_rcdn.go | 8 +- .../rainyun-rcdn/rainyun_rcdn_test.go | 4 +- .../ratpanel-console/ratpanel_console.go | 26 +- .../providers/ratpanel-site/ratpanel_site.go | 25 +- .../deployer/providers/safeline/safeline.go | 15 +- .../tencentcloud_gaap_test.go | 5 - .../unicloud-webhost/unicloud_webhost.go | 11 +- .../deployer/providers/upyun-cdn/upyun_cdn.go | 12 +- .../providers/wangsu-cdn/wangsu_cdn.go | 11 +- .../providers/wangsu-cdnpro/wangsu_cdnpro.go | 20 +- .../wangsu-certificate/wangsu_certificate.go | 11 +- .../providers/discordbot/discordbot_test.go | 2 +- .../providers/slackbot/slackbot_test.go | 2 +- .../providers/1panel-ssl/1panel_ssl.go | 173 +++++++++---- .../azure-keyvault/azure_keyvault.go | 8 +- .../uploader/providers/dogecloud/dogecloud.go | 12 +- .../uploader/providers/gcore-cdn/gcore_cdn.go | 2 +- .../providers/qiniu-sslcert/qiniu_sslcert.go | 6 +- .../rainyun-sslcenter/rainyun_sslcenter.go | 9 +- .../uploader/providers/upyun-ssl/upyun_ssl.go | 12 +- .../wangsu-certificate/wangsu_certificate.go | 13 +- internal/pkg/sdk3rd/1panel/api.go | 60 ----- .../pkg/sdk3rd/1panel/api_get_https_conf.go | 43 ++++ .../pkg/sdk3rd/1panel/api_get_website_ssl.go | 50 ++++ .../sdk3rd/1panel/api_search_website_ssl.go | 50 ++++ .../sdk3rd/1panel/api_update_https_conf.go | 53 ++++ .../sdk3rd/1panel/api_update_settings_ssl.go | 40 +++ .../sdk3rd/1panel/api_upload_website_ssl.go | 41 +++ internal/pkg/sdk3rd/1panel/client.go | 99 ++++--- internal/pkg/sdk3rd/1panel/models.go | 131 ---------- internal/pkg/sdk3rd/1panel/types.go | 29 +++ .../sdk3rd/1panel/v2/api_get_https_conf.go | 43 ++++ .../sdk3rd/1panel/v2/api_get_website_ssl.go | 50 ++++ .../1panel/v2/api_search_website_ssl.go | 50 ++++ .../1panel/v2/api_update_core_settings_ssl.go | 40 +++ .../sdk3rd/1panel/v2/api_update_https_conf.go | 53 ++++ .../1panel/v2/api_upload_website_ssl.go | 41 +++ internal/pkg/sdk3rd/1panel/v2/client.go | 116 +++++++++ internal/pkg/sdk3rd/1panel/v2/types.go | 29 +++ internal/pkg/sdk3rd/apisix/api.go | 16 -- internal/pkg/sdk3rd/apisix/api_update_ssl.go | 44 ++++ internal/pkg/sdk3rd/apisix/client.go | 87 ++++--- internal/pkg/sdk3rd/apisix/models.go | 12 - internal/pkg/sdk3rd/apisix/types.go | 7 + .../sdk3rd/azure/{common => env}/config.go | 16 +- .../baiducloud/cert/{api.go => cert.go} | 0 internal/pkg/sdk3rd/baiducloud/cert/client.go | 1 + .../baiducloud/cert/{models.go => model.go} | 0 internal/pkg/sdk3rd/baishan/api.go | 23 -- .../sdk3rd/baishan/api_get_domain_config.go | 49 ++++ .../baishan/api_set_domain_certificate.go | 40 +++ .../sdk3rd/baishan/api_set_domain_config.go | 40 +++ internal/pkg/sdk3rd/baishan/client.go | 100 ++++---- internal/pkg/sdk3rd/baishan/models.go | 82 ------ internal/pkg/sdk3rd/baishan/types.go | 49 ++++ internal/pkg/sdk3rd/btpanel/api.go | 31 --- .../btpanel/api_config_save_panel_ssl.go | 35 +++ .../pkg/sdk3rd/btpanel/api_site_set_ssl.go | 37 +++ .../sdk3rd/btpanel/api_ssl_cert_save_cert.go | 37 +++ .../btpanel/api_ssl_set_batch_cert_to_site.go | 44 ++++ .../btpanel/api_system_service_admin.go | 35 +++ internal/pkg/sdk3rd/btpanel/client.go | 139 ++++++---- internal/pkg/sdk3rd/btpanel/models.go | 75 ------ internal/pkg/sdk3rd/btpanel/types.go | 19 ++ internal/pkg/sdk3rd/btwaf/api.go | 19 -- .../pkg/sdk3rd/btwaf/api_config_set_cert.go | 36 +++ .../pkg/sdk3rd/btwaf/api_get_site_list.go | 42 +++ internal/pkg/sdk3rd/btwaf/api_modify_site.go | 37 +++ internal/pkg/sdk3rd/btwaf/client.go | 79 ++++-- internal/pkg/sdk3rd/btwaf/models.go | 67 ----- internal/pkg/sdk3rd/btwaf/types.go | 39 +++ internal/pkg/sdk3rd/bunny/api.go | 16 -- .../bunny/api_add_custom_certificate.go | 38 +++ internal/pkg/sdk3rd/bunny/client.go | 61 ++--- internal/pkg/sdk3rd/bunny/models.go | 8 - internal/pkg/sdk3rd/cachefly/api.go | 11 - .../sdk3rd/cachefly/api_create_certificate.go | 50 ++++ internal/pkg/sdk3rd/cachefly/client.go | 81 +++--- internal/pkg/sdk3rd/cachefly/models.go | 38 --- internal/pkg/sdk3rd/cachefly/types.go | 19 ++ internal/pkg/sdk3rd/cdnfly/api.go | 43 ---- internal/pkg/sdk3rd/cdnfly/api_create_cert.go | 41 +++ internal/pkg/sdk3rd/cdnfly/api_get_site.go | 43 ++++ internal/pkg/sdk3rd/cdnfly/api_update_cert.go | 46 ++++ internal/pkg/sdk3rd/cdnfly/api_update_site.go | 42 +++ internal/pkg/sdk3rd/cdnfly/client.go | 99 ++++--- internal/pkg/sdk3rd/cdnfly/models.go | 84 ------ internal/pkg/sdk3rd/cdnfly/types.go | 46 ++++ .../pkg/sdk3rd/ctyun/ao/api_create_cert.go | 2 +- .../sdk3rd/ctyun/ao/api_get_domain_config.go | 10 +- .../pkg/sdk3rd/ctyun/ao/api_list_certs.go | 2 +- .../ctyun/ao/api_modify_domain_config.go | 2 +- .../pkg/sdk3rd/ctyun/ao/api_query_cert.go | 2 +- internal/pkg/sdk3rd/ctyun/ao/client.go | 15 +- internal/pkg/sdk3rd/ctyun/ao/types.go | 14 +- .../pkg/sdk3rd/ctyun/cdn/api_create_cert.go | 2 +- .../sdk3rd/ctyun/cdn/api_query_cert_detail.go | 2 +- .../sdk3rd/ctyun/cdn/api_query_cert_list.go | 2 +- .../ctyun/cdn/api_query_domain_detail.go | 2 +- .../pkg/sdk3rd/ctyun/cdn/api_update_domain.go | 2 +- internal/pkg/sdk3rd/ctyun/cdn/client.go | 15 +- internal/pkg/sdk3rd/ctyun/cdn/types.go | 14 +- .../ctyun/cms/api_get_certificate_list.go | 2 +- .../ctyun/cms/api_upload_certificate.go | 2 +- internal/pkg/sdk3rd/ctyun/cms/client.go | 16 +- internal/pkg/sdk3rd/ctyun/cms/types.go | 14 +- .../pkg/sdk3rd/ctyun/dns/api_add_record.go | 2 +- .../pkg/sdk3rd/ctyun/dns/api_delete_record.go | 2 +- .../sdk3rd/ctyun/dns/api_query_record_list.go | 22 +- .../pkg/sdk3rd/ctyun/dns/api_update_record.go | 2 +- internal/pkg/sdk3rd/ctyun/dns/client.go | 16 +- internal/pkg/sdk3rd/ctyun/dns/types.go | 14 +- .../ctyun/elb/api_create_certificate.go | 2 +- .../sdk3rd/ctyun/elb/api_list_certificates.go | 2 +- .../sdk3rd/ctyun/elb/api_list_listeners.go | 2 +- .../pkg/sdk3rd/ctyun/elb/api_show_listener.go | 2 +- .../sdk3rd/ctyun/elb/api_update_listener.go | 2 +- internal/pkg/sdk3rd/ctyun/elb/client.go | 16 +- internal/pkg/sdk3rd/ctyun/elb/types.go | 14 +- .../pkg/sdk3rd/ctyun/icdn/api_create_cert.go | 2 +- .../ctyun/icdn/api_query_cert_detail.go | 2 +- .../sdk3rd/ctyun/icdn/api_query_cert_list.go | 2 +- .../ctyun/icdn/api_query_domain_detail.go | 2 +- .../sdk3rd/ctyun/icdn/api_update_domain.go | 2 +- internal/pkg/sdk3rd/ctyun/icdn/client.go | 15 +- internal/pkg/sdk3rd/ctyun/icdn/types.go | 14 +- .../pkg/sdk3rd/ctyun/lvdn/api_create_cert.go | 2 +- .../ctyun/lvdn/api_query_cert_detail.go | 2 +- .../sdk3rd/ctyun/lvdn/api_query_cert_list.go | 2 +- .../ctyun/lvdn/api_query_domain_detail.go | 2 +- .../sdk3rd/ctyun/lvdn/api_update_domain.go | 2 +- internal/pkg/sdk3rd/ctyun/lvdn/client.go | 15 +- internal/pkg/sdk3rd/ctyun/lvdn/types.go | 14 +- internal/pkg/sdk3rd/ctyun/openapi/client.go | 36 ++- internal/pkg/sdk3rd/dcloud/unicloud/api.go | 78 ------ .../unicloud/api_create_domain_with_cert.go | 27 ++ internal/pkg/sdk3rd/dcloud/unicloud/client.go | 160 +++++++++--- internal/pkg/sdk3rd/dcloud/unicloud/models.go | 103 -------- internal/pkg/sdk3rd/dcloud/unicloud/types.go | 64 +++++ internal/pkg/sdk3rd/dnsla/api.go | 41 --- .../pkg/sdk3rd/dnsla/api_create_record.go | 46 ++++ .../pkg/sdk3rd/dnsla/api_delete_record.go | 36 +++ internal/pkg/sdk3rd/dnsla/api_list_domains.go | 51 ++++ internal/pkg/sdk3rd/dnsla/api_list_records.go | 71 +++++ .../pkg/sdk3rd/dnsla/api_update_record.go | 43 ++++ internal/pkg/sdk3rd/dnsla/client.go | 89 ++++--- internal/pkg/sdk3rd/dnsla/models.go | 131 ---------- internal/pkg/sdk3rd/dnsla/types.go | 59 +++++ .../pkg/sdk3rd/dogecloud/api_bind_cdn_cert.go | 36 +++ .../sdk3rd/dogecloud/api_upload_cdn_cert.go | 41 +++ internal/pkg/sdk3rd/dogecloud/client.go | 242 +++++++----------- internal/pkg/sdk3rd/dogecloud/models.go | 31 --- internal/pkg/sdk3rd/dogecloud/types.go | 29 +++ internal/pkg/sdk3rd/flexcdn/api.go | 48 ---- .../pkg/sdk3rd/flexcdn/api_update_ssl_cert.go | 50 ++++ internal/pkg/sdk3rd/flexcdn/client.go | 143 ++++++++--- internal/pkg/sdk3rd/flexcdn/models.go | 52 ---- internal/pkg/sdk3rd/flexcdn/types.go | 21 ++ .../pkg/sdk3rd/gcore/{common => }/endpoint.go | 0 .../pkg/sdk3rd/gcore/{common => }/signer.go | 0 internal/pkg/sdk3rd/gname/api.go | 25 -- .../sdk3rd/gname/api_add_domain_resolution.go | 42 +++ .../gname/api_delete_domain_resolution.go | 35 +++ .../gname/api_list_domain_resolution.go | 41 +++ .../gname/api_modify_domain_resolution.go | 40 +++ internal/pkg/sdk3rd/gname/client.go | 138 ++++++---- internal/pkg/sdk3rd/gname/models.go | 81 ------ internal/pkg/sdk3rd/gname/types.go | 32 +++ internal/pkg/sdk3rd/goedge/api.go | 48 ---- .../pkg/sdk3rd/goedge/api_update_ssl_cert.go | 50 ++++ internal/pkg/sdk3rd/goedge/client.go | 143 ++++++++--- internal/pkg/sdk3rd/goedge/models.go | 52 ---- internal/pkg/sdk3rd/goedge/types.go | 21 ++ .../lecdn/client-v3/api_update_certificate.go | 49 ++++ internal/pkg/sdk3rd/lecdn/client-v3/client.go | 161 ++++++++++++ internal/pkg/sdk3rd/lecdn/client-v3/types.go | 21 ++ .../lecdn/master-v3/api_update_certificate.go | 50 ++++ internal/pkg/sdk3rd/lecdn/master-v3/client.go | 162 ++++++++++++ internal/pkg/sdk3rd/lecdn/master-v3/types.go | 21 ++ internal/pkg/sdk3rd/lecdn/v3/client/api.go | 50 ---- internal/pkg/sdk3rd/lecdn/v3/client/client.go | 100 -------- internal/pkg/sdk3rd/lecdn/v3/client/models.go | 47 ---- internal/pkg/sdk3rd/lecdn/v3/master/api.go | 49 ---- internal/pkg/sdk3rd/lecdn/v3/master/client.go | 100 -------- internal/pkg/sdk3rd/lecdn/v3/master/models.go | 47 ---- internal/pkg/sdk3rd/netlify/api.go | 17 -- .../api_provision_site_tls_certificate.go | 52 ++++ internal/pkg/sdk3rd/netlify/client.go | 94 ++++--- internal/pkg/sdk3rd/netlify/models.go | 40 --- internal/pkg/sdk3rd/netlify/types.go | 29 +++ internal/pkg/sdk3rd/qiniu/auth.go | 3 +- internal/pkg/sdk3rd/qiniu/cdn.go | 134 ++++++++++ internal/pkg/sdk3rd/qiniu/client.go | 85 ------ internal/pkg/sdk3rd/qiniu/models.go | 54 ---- internal/pkg/sdk3rd/rainyun/api.go | 38 --- .../rainyun/api_rcdn_instance_ssl_bind.go | 41 +++ .../sdk3rd/rainyun/api_ssl_center_create.go | 36 +++ .../pkg/sdk3rd/rainyun/api_ssl_center_get.go | 37 +++ .../pkg/sdk3rd/rainyun/api_ssl_center_list.go | 49 ++++ internal/pkg/sdk3rd/rainyun/client.go | 77 ++++-- internal/pkg/sdk3rd/rainyun/models.go | 83 ------ internal/pkg/sdk3rd/rainyun/types.go | 49 ++++ internal/pkg/sdk3rd/ratpanel/api.go | 15 -- .../sdk3rd/ratpanel/api_set_setting_cert.go | 36 +++ .../sdk3rd/ratpanel/api_set_website_cert.go | 37 +++ internal/pkg/sdk3rd/ratpanel/client.go | 106 +++++--- internal/pkg/sdk3rd/ratpanel/models.go | 35 --- internal/pkg/sdk3rd/ratpanel/types.go | 19 ++ internal/pkg/sdk3rd/safeline/api.go | 7 - .../sdk3rd/safeline/api_update_certificate.go | 37 +++ internal/pkg/sdk3rd/safeline/client.go | 78 ++++-- internal/pkg/sdk3rd/safeline/models.go | 34 --- internal/pkg/sdk3rd/safeline/types.go | 34 +++ .../sdk3rd/ucloud/udnr/api_add_domain_dns.go | 44 ++++ .../ucloud/udnr/api_delete_domain_dns.go | 42 +++ .../ucloud/udnr/api_query_domain_dns.go | 41 +++ internal/pkg/sdk3rd/ucloud/udnr/apis.go | 115 --------- .../ucloud/udnr/{models.go => types.go} | 0 .../{apis.go => api_add_ufile_ssl_cert.go} | 0 .../ucloud/ussl/api_download_certificate.go | 43 ++++ .../ussl/api_get_certificate_detail_info.go | 41 +++ .../ucloud/ussl/api_get_certificate_list.go | 49 ++++ .../ussl/api_upload_normal_certificate.go | 46 ++++ internal/pkg/sdk3rd/ucloud/ussl/apis.go | 161 ------------ .../ucloud/ussl/{models.go => types.go} | 0 internal/pkg/sdk3rd/upyun/console/api.go | 83 ------ .../api_get_https_certificate_manager.go | 55 ++++ .../console/api_get_https_service_manager.go | 60 +++++ .../upyun/console/api_migrate_https_domain.go | 46 ++++ .../api_update_https_certificate_manager.go | 48 ++++ .../console/api_upload_https_certificate.go | 51 ++++ internal/pkg/sdk3rd/upyun/console/client.go | 130 +++++++--- internal/pkg/sdk3rd/upyun/console/models.go | 141 ---------- internal/pkg/sdk3rd/upyun/console/types.go | 41 +++ internal/pkg/sdk3rd/wangsu/cdn/api.go | 15 -- .../api_batch_update_certificate_config.go | 36 +++ internal/pkg/sdk3rd/wangsu/cdn/client.go | 35 ++- internal/pkg/sdk3rd/wangsu/cdn/models.go | 26 -- internal/pkg/sdk3rd/wangsu/cdn/types.go | 29 +++ internal/pkg/sdk3rd/wangsu/cdnpro/api.go | 70 ----- .../wangsu/cdnpro/api_create_certificate.go | 46 ++++ .../cdnpro/api_create_deployment_task.go | 42 +++ .../cdnpro/api_get_deployment_task_detail.go | 45 ++++ .../wangsu/cdnpro/api_get_hostname_detail.go | 40 +++ .../wangsu/cdnpro/api_update_certificate.go | 51 ++++ internal/pkg/sdk3rd/wangsu/cdnpro/client.go | 27 +- internal/pkg/sdk3rd/wangsu/cdnpro/models.go | 108 -------- internal/pkg/sdk3rd/wangsu/cdnpro/types.go | 61 +++++ internal/pkg/sdk3rd/wangsu/certificate/api.go | 42 --- .../certificate/api_create_certificate.go | 42 +++ .../certificate/api_list_certificates.go | 32 +++ .../certificate/api_update_certificate.go | 44 ++++ .../pkg/sdk3rd/wangsu/certificate/client.go | 27 +- .../pkg/sdk3rd/wangsu/certificate/models.go | 52 ---- .../pkg/sdk3rd/wangsu/certificate/types.go | 38 +++ internal/pkg/sdk3rd/wangsu/openapi/client.go | 78 +++--- 280 files changed, 6923 insertions(+), 4658 deletions(-) delete mode 100644 internal/pkg/sdk3rd/1panel/api.go create mode 100644 internal/pkg/sdk3rd/1panel/api_get_https_conf.go create mode 100644 internal/pkg/sdk3rd/1panel/api_get_website_ssl.go create mode 100644 internal/pkg/sdk3rd/1panel/api_search_website_ssl.go create mode 100644 internal/pkg/sdk3rd/1panel/api_update_https_conf.go create mode 100644 internal/pkg/sdk3rd/1panel/api_update_settings_ssl.go create mode 100644 internal/pkg/sdk3rd/1panel/api_upload_website_ssl.go delete mode 100644 internal/pkg/sdk3rd/1panel/models.go create mode 100644 internal/pkg/sdk3rd/1panel/types.go create mode 100644 internal/pkg/sdk3rd/1panel/v2/api_get_https_conf.go create mode 100644 internal/pkg/sdk3rd/1panel/v2/api_get_website_ssl.go create mode 100644 internal/pkg/sdk3rd/1panel/v2/api_search_website_ssl.go create mode 100644 internal/pkg/sdk3rd/1panel/v2/api_update_core_settings_ssl.go create mode 100644 internal/pkg/sdk3rd/1panel/v2/api_update_https_conf.go create mode 100644 internal/pkg/sdk3rd/1panel/v2/api_upload_website_ssl.go create mode 100644 internal/pkg/sdk3rd/1panel/v2/client.go create mode 100644 internal/pkg/sdk3rd/1panel/v2/types.go delete mode 100644 internal/pkg/sdk3rd/apisix/api.go create mode 100644 internal/pkg/sdk3rd/apisix/api_update_ssl.go delete mode 100644 internal/pkg/sdk3rd/apisix/models.go create mode 100644 internal/pkg/sdk3rd/apisix/types.go rename internal/pkg/sdk3rd/azure/{common => env}/config.go (66%) rename internal/pkg/sdk3rd/baiducloud/cert/{api.go => cert.go} (100%) rename internal/pkg/sdk3rd/baiducloud/cert/{models.go => model.go} (100%) delete mode 100644 internal/pkg/sdk3rd/baishan/api.go create mode 100644 internal/pkg/sdk3rd/baishan/api_get_domain_config.go create mode 100644 internal/pkg/sdk3rd/baishan/api_set_domain_certificate.go create mode 100644 internal/pkg/sdk3rd/baishan/api_set_domain_config.go delete mode 100644 internal/pkg/sdk3rd/baishan/models.go create mode 100644 internal/pkg/sdk3rd/baishan/types.go delete mode 100644 internal/pkg/sdk3rd/btpanel/api.go create mode 100644 internal/pkg/sdk3rd/btpanel/api_config_save_panel_ssl.go create mode 100644 internal/pkg/sdk3rd/btpanel/api_site_set_ssl.go create mode 100644 internal/pkg/sdk3rd/btpanel/api_ssl_cert_save_cert.go create mode 100644 internal/pkg/sdk3rd/btpanel/api_ssl_set_batch_cert_to_site.go create mode 100644 internal/pkg/sdk3rd/btpanel/api_system_service_admin.go delete mode 100644 internal/pkg/sdk3rd/btpanel/models.go create mode 100644 internal/pkg/sdk3rd/btpanel/types.go delete mode 100644 internal/pkg/sdk3rd/btwaf/api.go create mode 100644 internal/pkg/sdk3rd/btwaf/api_config_set_cert.go create mode 100644 internal/pkg/sdk3rd/btwaf/api_get_site_list.go create mode 100644 internal/pkg/sdk3rd/btwaf/api_modify_site.go delete mode 100644 internal/pkg/sdk3rd/btwaf/models.go create mode 100644 internal/pkg/sdk3rd/btwaf/types.go delete mode 100644 internal/pkg/sdk3rd/bunny/api.go create mode 100644 internal/pkg/sdk3rd/bunny/api_add_custom_certificate.go delete mode 100644 internal/pkg/sdk3rd/bunny/models.go delete mode 100644 internal/pkg/sdk3rd/cachefly/api.go create mode 100644 internal/pkg/sdk3rd/cachefly/api_create_certificate.go delete mode 100644 internal/pkg/sdk3rd/cachefly/models.go create mode 100644 internal/pkg/sdk3rd/cachefly/types.go delete mode 100644 internal/pkg/sdk3rd/cdnfly/api.go create mode 100644 internal/pkg/sdk3rd/cdnfly/api_create_cert.go create mode 100644 internal/pkg/sdk3rd/cdnfly/api_get_site.go create mode 100644 internal/pkg/sdk3rd/cdnfly/api_update_cert.go create mode 100644 internal/pkg/sdk3rd/cdnfly/api_update_site.go delete mode 100644 internal/pkg/sdk3rd/cdnfly/models.go create mode 100644 internal/pkg/sdk3rd/cdnfly/types.go delete mode 100644 internal/pkg/sdk3rd/dcloud/unicloud/api.go create mode 100644 internal/pkg/sdk3rd/dcloud/unicloud/api_create_domain_with_cert.go delete mode 100644 internal/pkg/sdk3rd/dcloud/unicloud/models.go create mode 100644 internal/pkg/sdk3rd/dcloud/unicloud/types.go delete mode 100644 internal/pkg/sdk3rd/dnsla/api.go create mode 100644 internal/pkg/sdk3rd/dnsla/api_create_record.go create mode 100644 internal/pkg/sdk3rd/dnsla/api_delete_record.go create mode 100644 internal/pkg/sdk3rd/dnsla/api_list_domains.go create mode 100644 internal/pkg/sdk3rd/dnsla/api_list_records.go create mode 100644 internal/pkg/sdk3rd/dnsla/api_update_record.go delete mode 100644 internal/pkg/sdk3rd/dnsla/models.go create mode 100644 internal/pkg/sdk3rd/dnsla/types.go create mode 100644 internal/pkg/sdk3rd/dogecloud/api_bind_cdn_cert.go create mode 100644 internal/pkg/sdk3rd/dogecloud/api_upload_cdn_cert.go delete mode 100644 internal/pkg/sdk3rd/dogecloud/models.go create mode 100644 internal/pkg/sdk3rd/dogecloud/types.go delete mode 100644 internal/pkg/sdk3rd/flexcdn/api.go create mode 100644 internal/pkg/sdk3rd/flexcdn/api_update_ssl_cert.go delete mode 100644 internal/pkg/sdk3rd/flexcdn/models.go create mode 100644 internal/pkg/sdk3rd/flexcdn/types.go rename internal/pkg/sdk3rd/gcore/{common => }/endpoint.go (100%) rename internal/pkg/sdk3rd/gcore/{common => }/signer.go (100%) delete mode 100644 internal/pkg/sdk3rd/gname/api.go create mode 100644 internal/pkg/sdk3rd/gname/api_add_domain_resolution.go create mode 100644 internal/pkg/sdk3rd/gname/api_delete_domain_resolution.go create mode 100644 internal/pkg/sdk3rd/gname/api_list_domain_resolution.go create mode 100644 internal/pkg/sdk3rd/gname/api_modify_domain_resolution.go delete mode 100644 internal/pkg/sdk3rd/gname/models.go create mode 100644 internal/pkg/sdk3rd/gname/types.go delete mode 100644 internal/pkg/sdk3rd/goedge/api.go create mode 100644 internal/pkg/sdk3rd/goedge/api_update_ssl_cert.go delete mode 100644 internal/pkg/sdk3rd/goedge/models.go create mode 100644 internal/pkg/sdk3rd/goedge/types.go create mode 100644 internal/pkg/sdk3rd/lecdn/client-v3/api_update_certificate.go create mode 100644 internal/pkg/sdk3rd/lecdn/client-v3/client.go create mode 100644 internal/pkg/sdk3rd/lecdn/client-v3/types.go create mode 100644 internal/pkg/sdk3rd/lecdn/master-v3/api_update_certificate.go create mode 100644 internal/pkg/sdk3rd/lecdn/master-v3/client.go create mode 100644 internal/pkg/sdk3rd/lecdn/master-v3/types.go delete mode 100644 internal/pkg/sdk3rd/lecdn/v3/client/api.go delete mode 100644 internal/pkg/sdk3rd/lecdn/v3/client/client.go delete mode 100644 internal/pkg/sdk3rd/lecdn/v3/client/models.go delete mode 100644 internal/pkg/sdk3rd/lecdn/v3/master/api.go delete mode 100644 internal/pkg/sdk3rd/lecdn/v3/master/client.go delete mode 100644 internal/pkg/sdk3rd/lecdn/v3/master/models.go delete mode 100644 internal/pkg/sdk3rd/netlify/api.go create mode 100644 internal/pkg/sdk3rd/netlify/api_provision_site_tls_certificate.go delete mode 100644 internal/pkg/sdk3rd/netlify/models.go create mode 100644 internal/pkg/sdk3rd/netlify/types.go create mode 100644 internal/pkg/sdk3rd/qiniu/cdn.go delete mode 100644 internal/pkg/sdk3rd/qiniu/client.go delete mode 100644 internal/pkg/sdk3rd/qiniu/models.go delete mode 100644 internal/pkg/sdk3rd/rainyun/api.go create mode 100644 internal/pkg/sdk3rd/rainyun/api_rcdn_instance_ssl_bind.go create mode 100644 internal/pkg/sdk3rd/rainyun/api_ssl_center_create.go create mode 100644 internal/pkg/sdk3rd/rainyun/api_ssl_center_get.go create mode 100644 internal/pkg/sdk3rd/rainyun/api_ssl_center_list.go delete mode 100644 internal/pkg/sdk3rd/rainyun/models.go create mode 100644 internal/pkg/sdk3rd/rainyun/types.go delete mode 100644 internal/pkg/sdk3rd/ratpanel/api.go create mode 100644 internal/pkg/sdk3rd/ratpanel/api_set_setting_cert.go create mode 100644 internal/pkg/sdk3rd/ratpanel/api_set_website_cert.go delete mode 100644 internal/pkg/sdk3rd/ratpanel/models.go create mode 100644 internal/pkg/sdk3rd/ratpanel/types.go delete mode 100644 internal/pkg/sdk3rd/safeline/api.go create mode 100644 internal/pkg/sdk3rd/safeline/api_update_certificate.go delete mode 100644 internal/pkg/sdk3rd/safeline/models.go create mode 100644 internal/pkg/sdk3rd/safeline/types.go create mode 100644 internal/pkg/sdk3rd/ucloud/udnr/api_add_domain_dns.go create mode 100644 internal/pkg/sdk3rd/ucloud/udnr/api_delete_domain_dns.go create mode 100644 internal/pkg/sdk3rd/ucloud/udnr/api_query_domain_dns.go delete mode 100644 internal/pkg/sdk3rd/ucloud/udnr/apis.go rename internal/pkg/sdk3rd/ucloud/udnr/{models.go => types.go} (100%) rename internal/pkg/sdk3rd/ucloud/ufile/{apis.go => api_add_ufile_ssl_cert.go} (100%) create mode 100644 internal/pkg/sdk3rd/ucloud/ussl/api_download_certificate.go create mode 100644 internal/pkg/sdk3rd/ucloud/ussl/api_get_certificate_detail_info.go create mode 100644 internal/pkg/sdk3rd/ucloud/ussl/api_get_certificate_list.go create mode 100644 internal/pkg/sdk3rd/ucloud/ussl/api_upload_normal_certificate.go delete mode 100644 internal/pkg/sdk3rd/ucloud/ussl/apis.go rename internal/pkg/sdk3rd/ucloud/ussl/{models.go => types.go} (100%) delete mode 100644 internal/pkg/sdk3rd/upyun/console/api.go create mode 100644 internal/pkg/sdk3rd/upyun/console/api_get_https_certificate_manager.go create mode 100644 internal/pkg/sdk3rd/upyun/console/api_get_https_service_manager.go create mode 100644 internal/pkg/sdk3rd/upyun/console/api_migrate_https_domain.go create mode 100644 internal/pkg/sdk3rd/upyun/console/api_update_https_certificate_manager.go create mode 100644 internal/pkg/sdk3rd/upyun/console/api_upload_https_certificate.go delete mode 100644 internal/pkg/sdk3rd/upyun/console/models.go create mode 100644 internal/pkg/sdk3rd/upyun/console/types.go delete mode 100644 internal/pkg/sdk3rd/wangsu/cdn/api.go create mode 100644 internal/pkg/sdk3rd/wangsu/cdn/api_batch_update_certificate_config.go delete mode 100644 internal/pkg/sdk3rd/wangsu/cdn/models.go create mode 100644 internal/pkg/sdk3rd/wangsu/cdn/types.go delete mode 100644 internal/pkg/sdk3rd/wangsu/cdnpro/api.go create mode 100644 internal/pkg/sdk3rd/wangsu/cdnpro/api_create_certificate.go create mode 100644 internal/pkg/sdk3rd/wangsu/cdnpro/api_create_deployment_task.go create mode 100644 internal/pkg/sdk3rd/wangsu/cdnpro/api_get_deployment_task_detail.go create mode 100644 internal/pkg/sdk3rd/wangsu/cdnpro/api_get_hostname_detail.go create mode 100644 internal/pkg/sdk3rd/wangsu/cdnpro/api_update_certificate.go delete mode 100644 internal/pkg/sdk3rd/wangsu/cdnpro/models.go create mode 100644 internal/pkg/sdk3rd/wangsu/cdnpro/types.go delete mode 100644 internal/pkg/sdk3rd/wangsu/certificate/api.go create mode 100644 internal/pkg/sdk3rd/wangsu/certificate/api_create_certificate.go create mode 100644 internal/pkg/sdk3rd/wangsu/certificate/api_list_certificates.go create mode 100644 internal/pkg/sdk3rd/wangsu/certificate/api_update_certificate.go delete mode 100644 internal/pkg/sdk3rd/wangsu/certificate/models.go create mode 100644 internal/pkg/sdk3rd/wangsu/certificate/types.go diff --git a/internal/pkg/core/applicator/acme-dns01/lego-providers/azure-dns/azure-dns.go b/internal/pkg/core/applicator/acme-dns01/lego-providers/azure-dns/azure-dns.go index d8d54c90..d16252f7 100644 --- a/internal/pkg/core/applicator/acme-dns01/lego-providers/azure-dns/azure-dns.go +++ b/internal/pkg/core/applicator/acme-dns01/lego-providers/azure-dns/azure-dns.go @@ -6,7 +6,7 @@ import ( "github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/providers/dns/azuredns" - azcommon "github.com/usual2970/certimate/internal/pkg/sdk3rd/azure/common" + azenv "github.com/usual2970/certimate/internal/pkg/sdk3rd/azure/env" ) type ChallengeProviderConfig struct { @@ -28,7 +28,7 @@ func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, providerConfig.ClientID = config.ClientId providerConfig.ClientSecret = config.ClientSecret if config.CloudName != "" { - env, err := azcommon.GetCloudEnvironmentConfiguration(config.CloudName) + env, err := azenv.GetCloudEnvConfiguration(config.CloudName) if err != nil { return nil, err } diff --git a/internal/pkg/core/applicator/acme-dns01/lego-providers/dnsla/internal/lego.go b/internal/pkg/core/applicator/acme-dns01/lego-providers/dnsla/internal/lego.go index 1063ac5f..f4f6e59f 100644 --- a/internal/pkg/core/applicator/acme-dns01/lego-providers/dnsla/internal/lego.go +++ b/internal/pkg/core/applicator/acme-dns01/lego-providers/dnsla/internal/lego.go @@ -69,8 +69,12 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { return nil, errors.New("dnsla: the configuration of the DNS provider is nil") } - client := dnslasdk.NewClient(config.APIId, config.APISecret). - WithTimeout(config.HTTPTimeout) + client, err := dnslasdk.NewClient(config.APIId, config.APISecret) + if err != nil { + return nil, err + } else { + client.SetTimeout(config.HTTPTimeout) + } return &DNSProvider{ client: client, @@ -122,13 +126,13 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { return d.config.PropagationTimeout, d.config.PollingInterval } -func (d *DNSProvider) getDNSZone(zoneName string) (*dnslasdk.DomainInfo, error) { - pageIndex := 1 - pageSize := 100 +func (d *DNSProvider) getDNSZone(zoneName string) (*dnslasdk.DomainRecord, error) { + pageIndex := int32(1) + pageSize := int32(100) for { request := &dnslasdk.ListDomainsRequest{ - PageIndex: int32(pageIndex), - PageSize: int32(pageSize), + PageIndex: &pageIndex, + PageSize: &pageSize, } response, err := d.client.ListDomains(request) if err != nil { @@ -143,7 +147,7 @@ func (d *DNSProvider) getDNSZone(zoneName string) (*dnslasdk.DomainInfo, error) } } - if response.Data == nil || len(response.Data.Results) < pageSize { + if response.Data == nil || len(response.Data.Results) < int(pageSize) { break } @@ -153,20 +157,20 @@ func (d *DNSProvider) getDNSZone(zoneName string) (*dnslasdk.DomainInfo, error) return nil, fmt.Errorf("dnsla: zone %s not found", zoneName) } -func (d *DNSProvider) getDNSZoneAndRecord(zoneName, subDomain string) (*dnslasdk.DomainInfo, *dnslasdk.RecordInfo, error) { +func (d *DNSProvider) getDNSZoneAndRecord(zoneName, subDomain string) (*dnslasdk.DomainRecord, *dnslasdk.DnsRecord, error) { zone, err := d.getDNSZone(zoneName) if err != nil { return nil, nil, err } - pageIndex := 1 - pageSize := 100 + pageIndex := int32(1) + pageSize := int32(100) for { request := &dnslasdk.ListRecordsRequest{ - DomainId: zone.Id, + DomainId: &zone.Id, Host: &subDomain, - PageIndex: int32(pageIndex), - PageSize: int32(pageSize), + PageIndex: &pageIndex, + PageSize: &pageSize, } response, err := d.client.ListRecords(request) if err != nil { @@ -181,7 +185,7 @@ func (d *DNSProvider) getDNSZoneAndRecord(zoneName, subDomain string) (*dnslasdk } } - if response.Data == nil || len(response.Data.Results) < pageSize { + if response.Data == nil || len(response.Data.Results) < int(pageSize) { break } @@ -231,10 +235,7 @@ func (d *DNSProvider) removeDNSRecord(zoneName, subDomain string) error { if record == nil { return nil } else { - request := &dnslasdk.DeleteRecordRequest{ - Id: record.Id, - } - _, err = d.client.DeleteRecord(request) + _, err = d.client.DeleteRecord(record.Id) return err } } diff --git a/internal/pkg/core/applicator/acme-dns01/lego-providers/gname/internal/lego.go b/internal/pkg/core/applicator/acme-dns01/lego-providers/gname/internal/lego.go index 6bfda830..3435027e 100644 --- a/internal/pkg/core/applicator/acme-dns01/lego-providers/gname/internal/lego.go +++ b/internal/pkg/core/applicator/acme-dns01/lego-providers/gname/internal/lego.go @@ -10,6 +10,7 @@ import ( "github.com/go-acme/lego/v4/platform/config/env" gnamesdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/gname" + xtypes "github.com/usual2970/certimate/internal/pkg/utils/types" ) const ( @@ -68,8 +69,12 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { return nil, errors.New("gname: the configuration of the DNS provider is nil") } - client := gnamesdk.NewClient(config.AppID, config.AppKey). - WithTimeout(config.HTTPTimeout) + client, err := gnamesdk.NewClient(config.AppID, config.AppKey) + if err != nil { + return nil, err + } else { + client.SetTimeout(config.HTTPTimeout) + } return &DNSProvider{ client: client, @@ -121,14 +126,15 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { return d.config.PropagationTimeout, d.config.PollingInterval } -func (d *DNSProvider) findDNSRecord(zoneName, subDomain string) (*gnamesdk.ResolutionRecord, error) { +func (d *DNSProvider) findDNSRecord(zoneName, subDomain string) (*gnamesdk.DomainResolutionRecordord, error) { page := int32(1) pageSize := int32(20) for { - request := &gnamesdk.ListDomainResolutionRequest{} - request.ZoneName = zoneName - request.Page = &page - request.PageSize = &pageSize + request := &gnamesdk.ListDomainResolutionRequest{ + ZoneName: xtypes.ToPtr(zoneName), + Page: xtypes.ToPtr(page), + PageSize: xtypes.ToPtr(pageSize), + } response, err := d.client.ListDomainResolution(request) if err != nil { @@ -162,23 +168,23 @@ func (d *DNSProvider) addOrUpdateDNSRecord(zoneName, subDomain, value string) er if record == nil { request := &gnamesdk.AddDomainResolutionRequest{ - ZoneName: zoneName, - RecordType: "TXT", - RecordName: subDomain, - RecordValue: value, - TTL: int32(d.config.TTL), + ZoneName: xtypes.ToPtr(zoneName), + RecordType: xtypes.ToPtr("TXT"), + RecordName: xtypes.ToPtr(subDomain), + RecordValue: xtypes.ToPtr(value), + TTL: xtypes.ToPtr(int32(d.config.TTL)), } _, err := d.client.AddDomainResolution(request) return err } else { recordId, _ := record.ID.Int64() request := &gnamesdk.ModifyDomainResolutionRequest{ - ID: recordId, - ZoneName: zoneName, - RecordType: "TXT", - RecordName: subDomain, - RecordValue: value, - TTL: int32(d.config.TTL), + ID: xtypes.ToPtr(recordId), + ZoneName: xtypes.ToPtr(zoneName), + RecordType: xtypes.ToPtr("TXT"), + RecordName: xtypes.ToPtr(subDomain), + RecordValue: xtypes.ToPtr(value), + TTL: xtypes.ToPtr(int32(d.config.TTL)), } _, err := d.client.ModifyDomainResolution(request) return err @@ -197,8 +203,8 @@ func (d *DNSProvider) removeDNSRecord(zoneName, subDomain string) error { recordId, _ := record.ID.Int64() request := &gnamesdk.DeleteDomainResolutionRequest{ - ZoneName: zoneName, - RecordID: recordId, + ZoneName: xtypes.ToPtr(zoneName), + RecordID: xtypes.ToPtr(recordId), } _, err = d.client.DeleteDomainResolution(request) return err diff --git a/internal/pkg/core/applicator/acme-dns01/lego-providers/ucloud-udnr/internal/lego.go b/internal/pkg/core/applicator/acme-dns01/lego-providers/ucloud-udnr/internal/lego.go index e1be56a4..972f2fd3 100644 --- a/internal/pkg/core/applicator/acme-dns01/lego-providers/ucloud-udnr/internal/lego.go +++ b/internal/pkg/core/applicator/acme-dns01/lego-providers/ucloud-udnr/internal/lego.go @@ -71,6 +71,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { } cfg := ucloud.NewConfig() + cfg.Timeout = config.HTTPTimeout credential := auth.NewCredential() credential.PrivateKey = config.PrivateKey credential.PublicKey = config.PublicKey diff --git a/internal/pkg/core/deployer/providers/1panel-console/1panel_console.go b/internal/pkg/core/deployer/providers/1panel-console/1panel_console.go index 81d0a247..aa51c7ae 100644 --- a/internal/pkg/core/deployer/providers/1panel-console/1panel_console.go +++ b/internal/pkg/core/deployer/providers/1panel-console/1panel_console.go @@ -3,13 +3,13 @@ package onepanelconsole import ( "context" "crypto/tls" - "errors" "fmt" "log/slog" - "net/url" + "strconv" "github.com/usual2970/certimate/internal/pkg/core/deployer" onepanelsdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/1panel" + onepanelsdkv2 "github.com/usual2970/certimate/internal/pkg/sdk3rd/1panel/v2" ) type DeployerConfig struct { @@ -29,7 +29,7 @@ type DeployerConfig struct { type DeployerProvider struct { config *DeployerConfig logger *slog.Logger - sdkClient *onepanelsdk.Client + sdkClient any } var _ deployer.Deployer = (*DeployerProvider)(nil) @@ -62,48 +62,75 @@ func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer { func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPEM string) (*deployer.DeployResult, error) { // 设置面板 SSL 证书 - SSLEnable := "enable" - if d.config.ApiVersion == "v2" { - SSLEnable = "Enable" - } + switch sdkClient := d.sdkClient.(type) { + case *onepanelsdk.Client: + { + updateSettingsSSLReq := &onepanelsdk.UpdateSettingsSSLRequest{ + Cert: certPEM, + Key: privkeyPEM, + SSL: "enable", + SSLType: "import-paste", + AutoRestart: strconv.FormatBool(d.config.AutoRestart), + } + updateSystemSSLResp, err := sdkClient.UpdateSettingsSSL(updateSettingsSSLReq) + d.logger.Debug("sdk request '1panel.UpdateSettingsSSL'", slog.Any("request", updateSettingsSSLReq), slog.Any("response", updateSystemSSLResp)) + if err != nil { + return nil, fmt.Errorf("failed to execute sdk request '1panel.UpdateSettingsSSL': %w", err) + } + } - updateSystemSSLReq := &onepanelsdk.UpdateSystemSSLRequest{ - Cert: certPEM, - Key: privkeyPEM, - SSL: SSLEnable, - SSLType: "import-paste", - } - if d.config.AutoRestart { - updateSystemSSLReq.AutoRestart = "true" - } else { - updateSystemSSLReq.AutoRestart = "false" - } - updateSystemSSLResp, err := d.sdkClient.UpdateSystemSSL(updateSystemSSLReq) - d.logger.Debug("sdk request '1panel.UpdateSystemSSL'", slog.Any("request", updateSystemSSLReq), slog.Any("response", updateSystemSSLResp)) - if err != nil { - return nil, fmt.Errorf("failed to execute sdk request '1panel.UpdateSystemSSL': %w", err) + case *onepanelsdkv2.Client: + { + updateCoreSettingsSSLReq := &onepanelsdkv2.UpdateCoreSettingsSSLRequest{ + Cert: certPEM, + Key: privkeyPEM, + SSL: "Enable", + SSLType: "import-paste", + AutoRestart: strconv.FormatBool(d.config.AutoRestart), + } + updateCoreSystemSSLResp, err := sdkClient.UpdateCoreSettingsSSL(updateCoreSettingsSSLReq) + d.logger.Debug("sdk request '1panel.UpdateCoreSettingsSSL'", slog.Any("request", updateCoreSettingsSSLReq), slog.Any("response", updateCoreSystemSSLResp)) + if err != nil { + return nil, fmt.Errorf("failed to execute sdk request '1panel.UpdateCoreSettingsSSL': %w", err) + } + } + + default: + panic("sdk client is not implemented") } return &deployer.DeployResult{}, nil } -func createSdkClient(serverUrl, apiVersion, apiKey string, skipTlsVerify bool) (*onepanelsdk.Client, error) { - if _, err := url.Parse(serverUrl); err != nil { - return nil, errors.New("invalid 1panel server url") +const ( + sdkVersionV1 = "v1" + sdkVersionV2 = "v2" +) + +func createSdkClient(serverUrl, apiVersion, apiKey string, skipTlsVerify bool) (any, error) { + if apiVersion == sdkVersionV1 { + client, err := onepanelsdk.NewClient(serverUrl, apiKey) + if err != nil { + return nil, err + } + + if skipTlsVerify { + client.SetTLSConfig(&tls.Config{InsecureSkipVerify: true}) + } + + return client, nil + } else if apiVersion == sdkVersionV2 { + client, err := onepanelsdkv2.NewClient(serverUrl, apiKey) + if err != nil { + return nil, err + } + + if skipTlsVerify { + client.SetTLSConfig(&tls.Config{InsecureSkipVerify: true}) + } + + return client, nil } - if apiVersion == "" { - return nil, errors.New("invalid 1panel api version") - } - - if apiKey == "" { - return nil, errors.New("invalid 1panel api key") - } - - client := onepanelsdk.NewClient(serverUrl, apiVersion, apiKey) - if skipTlsVerify { - client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}) - } - - return client, nil + return nil, fmt.Errorf("invalid 1panel api version") } diff --git a/internal/pkg/core/deployer/providers/1panel-site/1panel_site.go b/internal/pkg/core/deployer/providers/1panel-site/1panel_site.go index 0f721c3f..a0bf9dfd 100644 --- a/internal/pkg/core/deployer/providers/1panel-site/1panel_site.go +++ b/internal/pkg/core/deployer/providers/1panel-site/1panel_site.go @@ -6,13 +6,13 @@ import ( "errors" "fmt" "log/slog" - "net/url" "strconv" "github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/uploader" uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/1panel-ssl" onepanelsdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/1panel" + onepanelsdkv2 "github.com/usual2970/certimate/internal/pkg/sdk3rd/1panel/v2" ) type DeployerConfig struct { @@ -38,7 +38,7 @@ type DeployerConfig struct { type DeployerProvider struct { config *DeployerConfig logger *slog.Logger - sdkClient *onepanelsdk.Client + sdkClient any sslUploader uploader.Uploader } @@ -107,16 +107,6 @@ func (d *DeployerProvider) deployToWebsite(ctx context.Context, certPEM string, return errors.New("config `websiteId` is required") } - // 获取网站 HTTPS 配置 - getHttpsConfReq := &onepanelsdk.GetHttpsConfRequest{ - WebsiteID: d.config.WebsiteId, - } - getHttpsConfResp, err := d.sdkClient.GetHttpsConf(getHttpsConfReq) - d.logger.Debug("sdk request '1panel.GetHttpsConf'", slog.Any("request", getHttpsConfReq), slog.Any("response", getHttpsConfResp)) - if err != nil { - return fmt.Errorf("failed to execute sdk request '1panel.GetHttpsConf': %w", err) - } - // 上传证书到面板 upres, err := d.sslUploader.Upload(ctx, certPEM, privkeyPEM) if err != nil { @@ -125,22 +115,65 @@ func (d *DeployerProvider) deployToWebsite(ctx context.Context, certPEM string, d.logger.Info("ssl certificate uploaded", slog.Any("result", upres)) } - // 修改网站 HTTPS 配置 - certId, _ := strconv.ParseInt(upres.CertId, 10, 64) - updateHttpsConfReq := &onepanelsdk.UpdateHttpsConfRequest{ - WebsiteID: d.config.WebsiteId, - Type: "existed", - WebsiteSSLID: certId, - Enable: getHttpsConfResp.Data.Enable, - HttpConfig: getHttpsConfResp.Data.HttpConfig, - SSLProtocol: getHttpsConfResp.Data.SSLProtocol, - Algorithm: getHttpsConfResp.Data.Algorithm, - Hsts: getHttpsConfResp.Data.Hsts, - } - updateHttpsConfResp, err := d.sdkClient.UpdateHttpsConf(updateHttpsConfReq) - d.logger.Debug("sdk request '1panel.UpdateHttpsConf'", slog.Any("request", updateHttpsConfReq), slog.Any("response", updateHttpsConfResp)) - if err != nil { - return fmt.Errorf("failed to execute sdk request '1panel.UpdateHttpsConf': %w", err) + switch sdkClient := d.sdkClient.(type) { + case *onepanelsdk.Client: + { + // 获取网站 HTTPS 配置 + getHttpsConfResp, err := sdkClient.GetHttpsConf(d.config.WebsiteId) + d.logger.Debug("sdk request '1panel.GetHttpsConf'", slog.Int64("websiteId", d.config.WebsiteId), slog.Any("response", getHttpsConfResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request '1panel.GetHttpsConf': %w", err) + } + + // 修改网站 HTTPS 配置 + certId, _ := strconv.ParseInt(upres.CertId, 10, 64) + updateHttpsConfReq := &onepanelsdk.UpdateHttpsConfRequest{ + WebsiteID: d.config.WebsiteId, + Type: "existed", + WebsiteSSLID: certId, + Enable: getHttpsConfResp.Data.Enable, + HttpConfig: getHttpsConfResp.Data.HttpConfig, + SSLProtocol: getHttpsConfResp.Data.SSLProtocol, + Algorithm: getHttpsConfResp.Data.Algorithm, + Hsts: getHttpsConfResp.Data.Hsts, + } + updateHttpsConfResp, err := sdkClient.UpdateHttpsConf(d.config.WebsiteId, updateHttpsConfReq) + d.logger.Debug("sdk request '1panel.UpdateHttpsConf'", slog.Int64("websiteId", d.config.WebsiteId), slog.Any("request", updateHttpsConfReq), slog.Any("response", updateHttpsConfResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request '1panel.UpdateHttpsConf': %w", err) + } + } + + case *onepanelsdkv2.Client: + { + // 获取网站 HTTPS 配置 + getHttpsConfResp, err := sdkClient.GetHttpsConf(d.config.WebsiteId) + d.logger.Debug("sdk request '1panel.GetHttpsConf'", slog.Int64("websiteId", d.config.WebsiteId), slog.Any("response", getHttpsConfResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request '1panel.GetHttpsConf': %w", err) + } + + // 修改网站 HTTPS 配置 + certId, _ := strconv.ParseInt(upres.CertId, 10, 64) + updateHttpsConfReq := &onepanelsdkv2.UpdateHttpsConfRequest{ + WebsiteID: d.config.WebsiteId, + Type: "existed", + WebsiteSSLID: certId, + Enable: getHttpsConfResp.Data.Enable, + HttpConfig: getHttpsConfResp.Data.HttpConfig, + SSLProtocol: getHttpsConfResp.Data.SSLProtocol, + Algorithm: getHttpsConfResp.Data.Algorithm, + Hsts: getHttpsConfResp.Data.Hsts, + } + updateHttpsConfResp, err := sdkClient.UpdateHttpsConf(d.config.WebsiteId, updateHttpsConfReq) + d.logger.Debug("sdk request '1panel.UpdateHttpsConf'", slog.Int64("websiteId", d.config.WebsiteId), slog.Any("request", updateHttpsConfReq), slog.Any("response", updateHttpsConfResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request '1panel.UpdateHttpsConf': %w", err) + } + } + + default: + panic("sdk client is not implemented") } return nil @@ -151,50 +184,91 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri return errors.New("config `certificateId` is required") } - // 获取证书详情 - getWebsiteSSLReq := &onepanelsdk.GetWebsiteSSLRequest{ - SSLID: d.config.CertificateId, - } - getWebsiteSSLResp, err := d.sdkClient.GetWebsiteSSL(getWebsiteSSLReq) - d.logger.Debug("sdk request '1panel.GetWebsiteSSL'", slog.Any("request", getWebsiteSSLReq), slog.Any("response", getWebsiteSSLResp)) - if err != nil { - return fmt.Errorf("failed to execute sdk request '1panel.GetWebsiteSSL': %w", err) - } + switch sdkClient := d.sdkClient.(type) { + case *onepanelsdk.Client: + { + // 获取证书详情 + getWebsiteSSLResp, err := sdkClient.GetWebsiteSSL(d.config.CertificateId) + d.logger.Debug("sdk request '1panel.GetWebsiteSSL'", slog.Any("sslId", d.config.CertificateId), slog.Any("response", getWebsiteSSLResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request '1panel.GetWebsiteSSL': %w", err) + } - // 更新证书 - uploadWebsiteSSLReq := &onepanelsdk.UploadWebsiteSSLRequest{ - Type: "paste", - SSLID: d.config.CertificateId, - Description: getWebsiteSSLResp.Data.Description, - Certificate: certPEM, - PrivateKey: privkeyPEM, - } - uploadWebsiteSSLResp, err := d.sdkClient.UploadWebsiteSSL(uploadWebsiteSSLReq) - d.logger.Debug("sdk request '1panel.UploadWebsiteSSL'", slog.Any("request", uploadWebsiteSSLReq), slog.Any("response", uploadWebsiteSSLResp)) - if err != nil { - return fmt.Errorf("failed to execute sdk request '1panel.UploadWebsiteSSL': %w", err) + // 更新证书 + uploadWebsiteSSLReq := &onepanelsdk.UploadWebsiteSSLRequest{ + SSLID: d.config.CertificateId, + Type: "paste", + Description: getWebsiteSSLResp.Data.Description, + Certificate: certPEM, + PrivateKey: privkeyPEM, + } + uploadWebsiteSSLResp, err := sdkClient.UploadWebsiteSSL(uploadWebsiteSSLReq) + d.logger.Debug("sdk request '1panel.UploadWebsiteSSL'", slog.Any("request", uploadWebsiteSSLReq), slog.Any("response", uploadWebsiteSSLResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request '1panel.UploadWebsiteSSL': %w", err) + } + } + + case *onepanelsdkv2.Client: + { + // 获取证书详情 + getWebsiteSSLResp, err := sdkClient.GetWebsiteSSL(d.config.CertificateId) + d.logger.Debug("sdk request '1panel.GetWebsiteSSL'", slog.Any("sslId", d.config.CertificateId), slog.Any("response", getWebsiteSSLResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request '1panel.GetWebsiteSSL': %w", err) + } + + // 更新证书 + uploadWebsiteSSLReq := &onepanelsdkv2.UploadWebsiteSSLRequest{ + SSLID: d.config.CertificateId, + Type: "paste", + Description: getWebsiteSSLResp.Data.Description, + Certificate: certPEM, + PrivateKey: privkeyPEM, + } + uploadWebsiteSSLResp, err := sdkClient.UploadWebsiteSSL(uploadWebsiteSSLReq) + d.logger.Debug("sdk request '1panel.UploadWebsiteSSL'", slog.Any("request", uploadWebsiteSSLReq), slog.Any("response", uploadWebsiteSSLResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request '1panel.UploadWebsiteSSL': %w", err) + } + } + + default: + panic("sdk client is not implemented") } return nil } -func createSdkClient(serverUrl, apiVersion, apiKey string, skipTlsVerify bool) (*onepanelsdk.Client, error) { - if _, err := url.Parse(serverUrl); err != nil { - return nil, errors.New("invalid 1panel server url") +const ( + sdkVersionV1 = "v1" + sdkVersionV2 = "v2" +) + +func createSdkClient(serverUrl, apiVersion, apiKey string, skipTlsVerify bool) (any, error) { + if apiVersion == sdkVersionV1 { + client, err := onepanelsdk.NewClient(serverUrl, apiKey) + if err != nil { + return nil, err + } + + if skipTlsVerify { + client.SetTLSConfig(&tls.Config{InsecureSkipVerify: true}) + } + + return client, nil + } else if apiVersion == sdkVersionV2 { + client, err := onepanelsdkv2.NewClient(serverUrl, apiKey) + if err != nil { + return nil, err + } + + if skipTlsVerify { + client.SetTLSConfig(&tls.Config{InsecureSkipVerify: true}) + } + + return client, nil } - if apiVersion == "" { - return nil, errors.New("invalid 1panel api version") - } - - if apiKey == "" { - return nil, errors.New("invalid 1panel api key") - } - - client := onepanelsdk.NewClient(serverUrl, apiVersion, apiKey) - if skipTlsVerify { - client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}) - } - - return client, nil + return nil, fmt.Errorf("invalid 1panel api version") } diff --git a/internal/pkg/core/deployer/providers/apisix/apisix.go b/internal/pkg/core/deployer/providers/apisix/apisix.go index 93778342..a64c54f4 100644 --- a/internal/pkg/core/deployer/providers/apisix/apisix.go +++ b/internal/pkg/core/deployer/providers/apisix/apisix.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "log/slog" - "net/url" "github.com/usual2970/certimate/internal/pkg/core/deployer" apisixsdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/apisix" @@ -91,15 +90,14 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri // 更新 SSL 证书 // REF: https://apisix.apache.org/zh/docs/apisix/admin-api/#ssl updateSSLReq := &apisixsdk.UpdateSSLRequest{ - ID: d.config.CertificateId, Cert: xtypes.ToPtr(certPEM), Key: xtypes.ToPtr(privkeyPEM), SNIs: xtypes.ToPtr(certX509.DNSNames), Type: xtypes.ToPtr("server"), Status: xtypes.ToPtr(int32(1)), } - updateSSLResp, err := d.sdkClient.UpdateSSL(updateSSLReq) - d.logger.Debug("sdk request 'apisix.UpdateSSL'", slog.Any("request", updateSSLReq), slog.Any("response", updateSSLResp)) + updateSSLResp, err := d.sdkClient.UpdateSSL(d.config.CertificateId, updateSSLReq) + d.logger.Debug("sdk request 'apisix.UpdateSSL'", slog.String("sslId", d.config.CertificateId), slog.Any("request", updateSSLReq), slog.Any("response", updateSSLResp)) if err != nil { return fmt.Errorf("failed to execute sdk request 'apisix.UpdateSSL': %w", err) } @@ -108,17 +106,13 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri } func createSdkClient(serverUrl, apiKey string, skipTlsVerify bool) (*apisixsdk.Client, error) { - if _, err := url.Parse(serverUrl); err != nil { - return nil, errors.New("invalid apisix server url") + client, err := apisixsdk.NewClient(serverUrl, apiKey) + if err != nil { + return nil, err } - if apiKey == "" { - return nil, errors.New("invalid apisix api key") - } - - client := apisixsdk.NewClient(serverUrl, apiKey) if skipTlsVerify { - client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}) + client.SetTLSConfig(&tls.Config{InsecureSkipVerify: true}) } return client, nil diff --git a/internal/pkg/core/deployer/providers/azure-keyvault/azure_keyvault.go b/internal/pkg/core/deployer/providers/azure-keyvault/azure_keyvault.go index 7261a4a1..1f4d0d73 100644 --- a/internal/pkg/core/deployer/providers/azure-keyvault/azure_keyvault.go +++ b/internal/pkg/core/deployer/providers/azure-keyvault/azure_keyvault.go @@ -16,7 +16,7 @@ import ( "github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/uploader" uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/azure-keyvault" - azcommon "github.com/usual2970/certimate/internal/pkg/sdk3rd/azure/common" + azenv "github.com/usual2970/certimate/internal/pkg/sdk3rd/azure/env" xcert "github.com/usual2970/certimate/internal/pkg/utils/cert" ) @@ -149,7 +149,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE } func createSdkClient(tenantId, clientId, clientSecret, cloudName, keyvaultName string) (*azcertificates.Client, error) { - env, err := azcommon.GetCloudEnvironmentConfiguration(cloudName) + env, err := azenv.GetCloudEnvConfiguration(cloudName) if err != nil { return nil, err } @@ -162,9 +162,9 @@ func createSdkClient(tenantId, clientId, clientSecret, cloudName, keyvaultName s } endpoint := fmt.Sprintf("https://%s.vault.azure.net", keyvaultName) - if azcommon.IsEnvironmentGovernment(cloudName) { + if azenv.IsUSGovernmentEnv(cloudName) { endpoint = fmt.Sprintf("https://%s.vault.usgovcloudapi.net", keyvaultName) - } else if azcommon.IsEnvironmentChina(cloudName) { + } else if azenv.IsChinaEnv(cloudName) { endpoint = fmt.Sprintf("https://%s.vault.azure.cn", keyvaultName) } diff --git a/internal/pkg/core/deployer/providers/baishan-cdn/baishan_cdn.go b/internal/pkg/core/deployer/providers/baishan-cdn/baishan_cdn.go index b056b076..daaafdc1 100644 --- a/internal/pkg/core/deployer/providers/baishan-cdn/baishan_cdn.go +++ b/internal/pkg/core/deployer/providers/baishan-cdn/baishan_cdn.go @@ -12,6 +12,7 @@ import ( "github.com/usual2970/certimate/internal/pkg/core/deployer" bssdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/baishan" + xtypes "github.com/usual2970/certimate/internal/pkg/utils/types" ) type DeployerConfig struct { @@ -68,34 +69,34 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE // 新增证书 // REF: https://portal.baishancloud.com/track/document/downloadPdf/1441 certificateId := "" - createCertificateReq := &bssdk.CreateCertificateRequest{ - Certificate: certPEM, - Key: privkeyPEM, - Name: fmt.Sprintf("certimate_%d", time.Now().UnixMilli()), + setDomainCertificateReq := &bssdk.SetDomainCertificateRequest{ + Name: xtypes.ToPtr(fmt.Sprintf("certimate_%d", time.Now().UnixMilli())), + Certificate: xtypes.ToPtr(certPEM), + Key: xtypes.ToPtr(privkeyPEM), } - createCertificateResp, err := d.sdkClient.CreateCertificate(createCertificateReq) - d.logger.Debug("sdk request 'baishan.CreateCertificate'", slog.Any("request", createCertificateReq), slog.Any("response", createCertificateResp)) + setDomainCertificateResp, err := d.sdkClient.SetDomainCertificate(setDomainCertificateReq) + d.logger.Debug("sdk request 'baishan.SetDomainCertificate'", slog.Any("request", setDomainCertificateReq), slog.Any("response", setDomainCertificateResp)) if err != nil { - if createCertificateResp != nil { - if createCertificateResp.GetCode() == 400699 && strings.Contains(createCertificateResp.GetMessage(), "this certificate is exists") { + if setDomainCertificateResp != nil { + if setDomainCertificateResp.GetCode() == 400699 && strings.Contains(setDomainCertificateResp.GetMessage(), "this certificate is exists") { // 证书已存在,忽略新增证书接口错误 re := regexp.MustCompile(`\d+`) - certificateId = re.FindString(createCertificateResp.GetMessage()) + certificateId = re.FindString(setDomainCertificateResp.GetMessage()) } } if certificateId == "" { - return nil, fmt.Errorf("failed to execute sdk request 'baishan.CreateCertificate': %w", err) + return nil, fmt.Errorf("failed to execute sdk request 'baishan.SetDomainCertificate': %w", err) } } else { - certificateId = createCertificateResp.Data.CertId.String() + certificateId = setDomainCertificateResp.Data.CertId.String() } // 查询域名配置 // REF: https://portal.baishancloud.com/track/document/api/1/1065 getDomainConfigReq := &bssdk.GetDomainConfigRequest{ - Domains: d.config.Domain, - Config: []string{"https"}, + Domains: xtypes.ToPtr(d.config.Domain), + Config: xtypes.ToPtr([]string{"https"}), } getDomainConfigResp, err := d.sdkClient.GetDomainConfig(getDomainConfigReq) d.logger.Debug("sdk request 'baishan.GetDomainConfig'", slog.Any("request", getDomainConfigReq), slog.Any("response", getDomainConfigResp)) @@ -108,7 +109,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE // 设置域名配置 // REF: https://portal.baishancloud.com/track/document/api/1/1045 setDomainConfigReq := &bssdk.SetDomainConfigRequest{ - Domains: d.config.Domain, + Domains: xtypes.ToPtr(d.config.Domain), Config: &bssdk.DomainConfig{ Https: &bssdk.DomainConfigHttps{ CertId: json.Number(certificateId), @@ -126,16 +127,16 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE } else { // 替换证书 // REF: https://portal.baishancloud.com/track/document/downloadPdf/1441 - createCertificateReq := &bssdk.CreateCertificateRequest{ + setDomainCertificateReq := &bssdk.SetDomainCertificateRequest{ CertificateId: &d.config.CertificateId, - Certificate: certPEM, - Key: privkeyPEM, - Name: fmt.Sprintf("certimate_%d", time.Now().UnixMilli()), + Name: xtypes.ToPtr(fmt.Sprintf("certimate_%d", time.Now().UnixMilli())), + Certificate: xtypes.ToPtr(certPEM), + Key: xtypes.ToPtr(privkeyPEM), } - createCertificateResp, err := d.sdkClient.CreateCertificate(createCertificateReq) - d.logger.Debug("sdk request 'baishan.CreateCertificate'", slog.Any("request", createCertificateReq), slog.Any("response", createCertificateResp)) + setDomainCertificateResp, err := d.sdkClient.SetDomainCertificate(setDomainCertificateReq) + d.logger.Debug("sdk request 'baishan.SetDomainCertificate'", slog.Any("request", setDomainCertificateReq), slog.Any("response", setDomainCertificateResp)) if err != nil { - return nil, fmt.Errorf("failed to execute sdk request 'baishan.CreateCertificate': %w", err) + return nil, fmt.Errorf("failed to execute sdk request 'baishan.SetDomainCertificate': %w", err) } } @@ -143,10 +144,5 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE } func createSdkClient(apiToken string) (*bssdk.Client, error) { - if apiToken == "" { - return nil, errors.New("invalid baishan api token") - } - - client := bssdk.NewClient(apiToken) - return client, nil + return bssdk.NewClient(apiToken) } diff --git a/internal/pkg/core/deployer/providers/baotapanel-console/baotapanel_console.go b/internal/pkg/core/deployer/providers/baotapanel-console/baotapanel_console.go index 403b96e8..2edbd4a7 100644 --- a/internal/pkg/core/deployer/providers/baotapanel-console/baotapanel_console.go +++ b/internal/pkg/core/deployer/providers/baotapanel-console/baotapanel_console.go @@ -3,10 +3,8 @@ package baotapanelconsole import ( "context" "crypto/tls" - "errors" "fmt" "log/slog" - "net/url" "github.com/usual2970/certimate/internal/pkg/core/deployer" btsdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/btpanel" @@ -83,17 +81,13 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE } func createSdkClient(serverUrl, apiKey string, skipTlsVerify bool) (*btsdk.Client, error) { - if _, err := url.Parse(serverUrl); err != nil { - return nil, errors.New("invalid baota server url") + client, err := btsdk.NewClient(serverUrl, apiKey) + if err != nil { + return nil, err } - if apiKey == "" { - return nil, errors.New("invalid baota api key") - } - - client := btsdk.NewClient(serverUrl, apiKey) if skipTlsVerify { - client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}) + client.SetTLSConfig(&tls.Config{InsecureSkipVerify: true}) } return client, nil diff --git a/internal/pkg/core/deployer/providers/baotapanel-site/baotapanel_site.go b/internal/pkg/core/deployer/providers/baotapanel-site/baotapanel_site.go index 563976ee..eca35af1 100644 --- a/internal/pkg/core/deployer/providers/baotapanel-site/baotapanel_site.go +++ b/internal/pkg/core/deployer/providers/baotapanel-site/baotapanel_site.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "log/slog" - "net/url" "github.com/usual2970/certimate/internal/pkg/core/deployer" btsdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/btpanel" @@ -125,17 +124,13 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE } func createSdkClient(serverUrl, apiKey string, skipTlsVerify bool) (*btsdk.Client, error) { - if _, err := url.Parse(serverUrl); err != nil { - return nil, errors.New("invalid baota server url") + client, err := btsdk.NewClient(serverUrl, apiKey) + if err != nil { + return nil, err } - if apiKey == "" { - return nil, errors.New("invalid baota api key") - } - - client := btsdk.NewClient(serverUrl, apiKey) if skipTlsVerify { - client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}) + client.SetTLSConfig(&tls.Config{InsecureSkipVerify: true}) } return client, nil diff --git a/internal/pkg/core/deployer/providers/baotawaf-console/baotawaf_console.go b/internal/pkg/core/deployer/providers/baotawaf-console/baotawaf_console.go index dbdbf811..0f81aab7 100644 --- a/internal/pkg/core/deployer/providers/baotawaf-console/baotawaf_console.go +++ b/internal/pkg/core/deployer/providers/baotawaf-console/baotawaf_console.go @@ -3,13 +3,12 @@ package baotapanelconsole import ( "context" "crypto/tls" - "errors" "fmt" "log/slog" - "net/url" "github.com/usual2970/certimate/internal/pkg/core/deployer" - btsdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/btwaf" + btwafsdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/btwaf" + xtypes "github.com/usual2970/certimate/internal/pkg/utils/types" ) type DeployerConfig struct { @@ -24,7 +23,7 @@ type DeployerConfig struct { type DeployerProvider struct { config *DeployerConfig logger *slog.Logger - sdkClient *btsdk.Client + sdkClient *btwafsdk.Client } var _ deployer.Deployer = (*DeployerProvider)(nil) @@ -57,31 +56,27 @@ func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer { func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPEM string) (*deployer.DeployResult, error) { // 设置面板 SSL - configSetSSLReq := &btsdk.ConfigSetSSLRequest{ - CertContent: certPEM, - KeyContent: privkeyPEM, + configSetCertReq := &btwafsdk.ConfigSetCertRequest{ + CertContent: xtypes.ToPtr(certPEM), + KeyContent: xtypes.ToPtr(privkeyPEM), } - configSetSSLResp, err := d.sdkClient.ConfigSetSSL(configSetSSLReq) - d.logger.Debug("sdk request 'bt.ConfigSetSSL'", slog.Any("request", configSetSSLReq), slog.Any("response", configSetSSLResp)) + configSetCertResp, err := d.sdkClient.ConfigSetCert(configSetCertReq) + d.logger.Debug("sdk request 'bt.ConfigSetCert'", slog.Any("request", configSetCertReq), slog.Any("response", configSetCertResp)) if err != nil { - return nil, fmt.Errorf("failed to execute sdk request 'bt.ConfigSetSSL': %w", err) + return nil, fmt.Errorf("failed to execute sdk request 'bt.ConfigSetCert': %w", err) } return &deployer.DeployResult{}, nil } -func createSdkClient(serverUrl, apiKey string, skipTlsVerify bool) (*btsdk.Client, error) { - if _, err := url.Parse(serverUrl); err != nil { - return nil, errors.New("invalid baota server url") +func createSdkClient(serverUrl, apiKey string, skipTlsVerify bool) (*btwafsdk.Client, error) { + client, err := btwafsdk.NewClient(serverUrl, apiKey) + if err != nil { + return nil, err } - if apiKey == "" { - return nil, errors.New("invalid baota api key") - } - - client := btsdk.NewClient(serverUrl, apiKey) if skipTlsVerify { - client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}) + client.SetTLSConfig(&tls.Config{InsecureSkipVerify: true}) } return client, nil diff --git a/internal/pkg/core/deployer/providers/baotawaf-site/baotawaf_site.go b/internal/pkg/core/deployer/providers/baotawaf-site/baotawaf_site.go index 5caf889d..8cb71441 100644 --- a/internal/pkg/core/deployer/providers/baotawaf-site/baotawaf_site.go +++ b/internal/pkg/core/deployer/providers/baotawaf-site/baotawaf_site.go @@ -6,10 +6,9 @@ import ( "errors" "fmt" "log/slog" - "net/url" "github.com/usual2970/certimate/internal/pkg/core/deployer" - btsdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/btwaf" + btwafsdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/btwaf" xtypes "github.com/usual2970/certimate/internal/pkg/utils/types" ) @@ -30,7 +29,7 @@ type DeployerConfig struct { type DeployerProvider struct { config *DeployerConfig logger *slog.Logger - sdkClient *btsdk.Client + sdkClient *btwafsdk.Client } var _ deployer.Deployer = (*DeployerProvider)(nil) @@ -81,7 +80,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE default: } - getSiteListReq := &btsdk.GetSiteListRequest{ + getSiteListReq := &btwafsdk.GetSiteListRequest{ SiteName: xtypes.ToPtr(d.config.SiteName), Page: xtypes.ToPtr(getSitListPage), PageSize: xtypes.ToPtr(getSitListPageSize), @@ -112,12 +111,12 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE } // 修改站点配置 - modifySiteReq := &btsdk.ModifySiteRequest{ - SiteId: siteId, + modifySiteReq := &btwafsdk.ModifySiteRequest{ + SiteId: xtypes.ToPtr(siteId), Type: xtypes.ToPtr("openCert"), - Server: &btsdk.SiteServerInfo{ + Server: &btwafsdk.SiteServerInfo{ ListenSSLPorts: xtypes.ToPtr([]int32{d.config.SitePort}), - SSL: &btsdk.SiteServerSSLInfo{ + SSL: &btwafsdk.SiteServerSSLInfo{ IsSSL: xtypes.ToPtr(int32(1)), FullChain: xtypes.ToPtr(certPEM), PrivateKey: xtypes.ToPtr(privkeyPEM), @@ -133,18 +132,14 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE return &deployer.DeployResult{}, nil } -func createSdkClient(serverUrl, apiKey string, skipTlsVerify bool) (*btsdk.Client, error) { - if _, err := url.Parse(serverUrl); err != nil { - return nil, errors.New("invalid baota server url") +func createSdkClient(serverUrl, apiKey string, skipTlsVerify bool) (*btwafsdk.Client, error) { + client, err := btwafsdk.NewClient(serverUrl, apiKey) + if err != nil { + return nil, err } - if apiKey == "" { - return nil, errors.New("invalid baota api key") - } - - client := btsdk.NewClient(serverUrl, apiKey) if skipTlsVerify { - client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}) + client.SetTLSConfig(&tls.Config{InsecureSkipVerify: true}) } return client, nil diff --git a/internal/pkg/core/deployer/providers/bunny-cdn/bunny_cdn.go b/internal/pkg/core/deployer/providers/bunny-cdn/bunny_cdn.go index cdc39baa..c59a6dd9 100644 --- a/internal/pkg/core/deployer/providers/bunny-cdn/bunny_cdn.go +++ b/internal/pkg/core/deployer/providers/bunny-cdn/bunny_cdn.go @@ -32,10 +32,15 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) { panic("config is nil") } + client, err := createSdkClient(config.ApiKey) + if err != nil { + return nil, fmt.Errorf("failed to create sdk client: %w", err) + } + return &DeployerProvider{ config: config, logger: slog.Default(), - sdkClient: bunnysdk.NewClient(config.ApiKey), + sdkClient: client, }, nil } @@ -49,18 +54,25 @@ func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer { } func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPEM string) (*deployer.DeployResult, error) { + if d.config.PullZoneId == "" { + return nil, fmt.Errorf("config `pullZoneId` is required") + } + // 上传证书 createCertificateReq := &bunnysdk.AddCustomCertificateRequest{ Hostname: d.config.Hostname, - PullZoneId: d.config.PullZoneId, Certificate: base64.StdEncoding.EncodeToString([]byte(certPEM)), CertificateKey: base64.StdEncoding.EncodeToString([]byte(privkeyPEM)), } - createCertificateResp, err := d.sdkClient.AddCustomCertificate(createCertificateReq) - d.logger.Debug("sdk request 'bunny.AddCustomCertificate'", slog.Any("request", createCertificateReq), slog.Any("response", createCertificateResp)) + err := d.sdkClient.AddCustomCertificate(d.config.PullZoneId, createCertificateReq) + d.logger.Debug("sdk request 'bunny.AddCustomCertificate'", slog.Any("request", createCertificateReq)) if err != nil { return nil, fmt.Errorf("failed to execute sdk request 'bunny.AddCustomCertificate': %w", err) } return &deployer.DeployResult{}, nil } + +func createSdkClient(apiKey string) (*bunnysdk.Client, error) { + return bunnysdk.NewClient(apiKey) +} diff --git a/internal/pkg/core/deployer/providers/cachefly/cachefly.go b/internal/pkg/core/deployer/providers/cachefly/cachefly.go index fa1cce13..823eb0b2 100644 --- a/internal/pkg/core/deployer/providers/cachefly/cachefly.go +++ b/internal/pkg/core/deployer/providers/cachefly/cachefly.go @@ -2,12 +2,12 @@ package cachefly import ( "context" - "errors" "fmt" "log/slog" "github.com/usual2970/certimate/internal/pkg/core/deployer" - cfsdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/cachefly" + cacheflysdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/cachefly" + xtypes "github.com/usual2970/certimate/internal/pkg/utils/types" ) type DeployerConfig struct { @@ -18,7 +18,7 @@ type DeployerConfig struct { type DeployerProvider struct { config *DeployerConfig logger *slog.Logger - sdkClient *cfsdk.Client + sdkClient *cacheflysdk.Client } var _ deployer.Deployer = (*DeployerProvider)(nil) @@ -52,9 +52,9 @@ func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer { func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPEM string) (*deployer.DeployResult, error) { // 上传证书 // REF: https://api.cachefly.com/api/2.5/docs#tag/Certificates/paths/~1certificates/post - createCertificateReq := &cfsdk.CreateCertificateRequest{ - Certificate: certPEM, - CertificateKey: privkeyPEM, + createCertificateReq := &cacheflysdk.CreateCertificateRequest{ + Certificate: xtypes.ToPtr(certPEM), + CertificateKey: xtypes.ToPtr(privkeyPEM), } createCertificateResp, err := d.sdkClient.CreateCertificate(createCertificateReq) d.logger.Debug("sdk request 'cachefly.CreateCertificate'", slog.Any("request", createCertificateReq), slog.Any("response", createCertificateResp)) @@ -65,11 +65,6 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE return &deployer.DeployResult{}, nil } -func createSdkClient(apiToken string) (*cfsdk.Client, error) { - if apiToken == "" { - return nil, errors.New("invalid cachefly api token") - } - - client := cfsdk.NewClient(apiToken) - return client, nil +func createSdkClient(apiToken string) (*cacheflysdk.Client, error) { + return cacheflysdk.NewClient(apiToken) } diff --git a/internal/pkg/core/deployer/providers/cdnfly/cdnfly.go b/internal/pkg/core/deployer/providers/cdnfly/cdnfly.go index 25fb6a54..c21b509a 100644 --- a/internal/pkg/core/deployer/providers/cdnfly/cdnfly.go +++ b/internal/pkg/core/deployer/providers/cdnfly/cdnfly.go @@ -7,11 +7,11 @@ import ( "errors" "fmt" "log/slog" - "net/url" "time" "github.com/usual2970/certimate/internal/pkg/core/deployer" - cfsdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/cdnfly" + cdnflysdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/cdnfly" + xtypes "github.com/usual2970/certimate/internal/pkg/utils/types" ) type DeployerConfig struct { @@ -36,7 +36,7 @@ type DeployerConfig struct { type DeployerProvider struct { config *DeployerConfig logger *slog.Logger - sdkClient *cfsdk.Client + sdkClient *cdnflysdk.Client } var _ deployer.Deployer = (*DeployerProvider)(nil) @@ -94,27 +94,24 @@ func (d *DeployerProvider) deployToSite(ctx context.Context, certPEM string, pri // 获取单个网站详情 // REF: https://doc.cdnfly.cn/wangzhanguanli-v1-sites.html#%E8%8E%B7%E5%8F%96%E5%8D%95%E4%B8%AA%E7%BD%91%E7%AB%99%E8%AF%A6%E6%83%85 - getSiteReq := &cfsdk.GetSiteRequest{ - Id: d.config.SiteId, - } - getSiteResp, err := d.sdkClient.GetSite(getSiteReq) - d.logger.Debug("sdk request 'cdnfly.GetSite'", slog.Any("request", getSiteReq), slog.Any("response", getSiteResp)) + getSiteResp, err := d.sdkClient.GetSite(d.config.SiteId) + d.logger.Debug("sdk request 'cdnfly.GetSite'", slog.Any("siteId", d.config.SiteId), slog.Any("response", getSiteResp)) if err != nil { return fmt.Errorf("failed to execute sdk request 'cdnfly.GetSite': %w", err) } // 添加单个证书 // REF: https://doc.cdnfly.cn/wangzhanzhengshu-v1-certs.html#%E6%B7%BB%E5%8A%A0%E5%8D%95%E4%B8%AA%E6%88%96%E5%A4%9A%E4%B8%AA%E8%AF%81%E4%B9%A6-%E5%A4%9A%E4%B8%AA%E8%AF%81%E4%B9%A6%E6%97%B6%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F%E4%B8%BA%E6%95%B0%E7%BB%84 - createCertificateReq := &cfsdk.CreateCertificateRequest{ - Name: fmt.Sprintf("certimate-%d", time.Now().UnixMilli()), - Type: "custom", - Cert: certPEM, - Key: privkeyPEM, + createCertificateReq := &cdnflysdk.CreateCertRequest{ + Name: xtypes.ToPtr(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())), + Type: xtypes.ToPtr("custom"), + Cert: xtypes.ToPtr(certPEM), + Key: xtypes.ToPtr(privkeyPEM), } - createCertificateResp, err := d.sdkClient.CreateCertificate(createCertificateReq) - d.logger.Debug("sdk request 'cdnfly.CreateCertificate'", slog.Any("request", createCertificateReq), slog.Any("response", createCertificateResp)) + createCertificateResp, err := d.sdkClient.CreateCert(createCertificateReq) + d.logger.Debug("sdk request 'cdnfly.CreateCert'", slog.Any("request", createCertificateReq), slog.Any("response", createCertificateResp)) if err != nil { - return fmt.Errorf("failed to execute sdk request 'cdnfly.CreateCertificate': %w", err) + return fmt.Errorf("failed to execute sdk request 'cdnfly.CreateCert': %w", err) } // 修改单个网站 @@ -123,13 +120,11 @@ func (d *DeployerProvider) deployToSite(ctx context.Context, certPEM string, pri _ = json.Unmarshal([]byte(getSiteResp.Data.HttpsListen), &updateSiteHttpsListenMap) updateSiteHttpsListenMap["cert"] = createCertificateResp.Data updateSiteHttpsListenData, _ := json.Marshal(updateSiteHttpsListenMap) - updateSiteHttpsListen := string(updateSiteHttpsListenData) - updateSiteReq := &cfsdk.UpdateSiteRequest{ - Id: d.config.SiteId, - HttpsListen: &updateSiteHttpsListen, + updateSiteReq := &cdnflysdk.UpdateSiteRequest{ + HttpsListen: xtypes.ToPtr(string(updateSiteHttpsListenData)), } - updateSiteResp, err := d.sdkClient.UpdateSite(updateSiteReq) - d.logger.Debug("sdk request 'cdnfly.UpdateSite'", slog.Any("request", updateSiteReq), slog.Any("response", updateSiteResp)) + updateSiteResp, err := d.sdkClient.UpdateSite(d.config.SiteId, updateSiteReq) + d.logger.Debug("sdk request 'cdnfly.UpdateSite'", slog.String("siteId", d.config.SiteId), slog.Any("request", updateSiteReq), slog.Any("response", updateSiteResp)) if err != nil { return fmt.Errorf("failed to execute sdk request 'cdnfly.UpdateSite': %w", err) } @@ -144,38 +139,28 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri // 修改单个证书 // REF: https://doc.cdnfly.cn/wangzhanzhengshu-v1-certs.html#%E4%BF%AE%E6%94%B9%E5%8D%95%E4%B8%AA%E8%AF%81%E4%B9%A6 - updateCertificateType := "custom" - updateCertificateReq := &cfsdk.UpdateCertificateRequest{ - Id: d.config.CertificateId, - Type: &updateCertificateType, - Cert: &certPEM, - Key: &privkeyPEM, + updateCertReq := &cdnflysdk.UpdateCertRequest{ + Type: xtypes.ToPtr("custom"), + Cert: xtypes.ToPtr(certPEM), + Key: xtypes.ToPtr(privkeyPEM), } - updateCertificateResp, err := d.sdkClient.UpdateCertificate(updateCertificateReq) - d.logger.Debug("sdk request 'cdnfly.UpdateCertificate'", slog.Any("request", updateCertificateReq), slog.Any("response", updateCertificateResp)) + updateCertResp, err := d.sdkClient.UpdateCert(d.config.CertificateId, updateCertReq) + d.logger.Debug("sdk request 'cdnfly.UpdateCert'", slog.String("certId", d.config.CertificateId), slog.Any("request", updateCertReq), slog.Any("response", updateCertResp)) if err != nil { - return fmt.Errorf("failed to execute sdk request 'cdnfly.UpdateCertificate': %w", err) + return fmt.Errorf("failed to execute sdk request 'cdnfly.UpdateCert': %w", err) } return nil } -func createSdkClient(serverUrl, apiKey, apiSecret string, skipTlsVerify bool) (*cfsdk.Client, error) { - if _, err := url.Parse(serverUrl); err != nil { - return nil, errors.New("invalid cachefly server url") +func createSdkClient(serverUrl, apiKey, apiSecret string, skipTlsVerify bool) (*cdnflysdk.Client, error) { + client, err := cdnflysdk.NewClient(serverUrl, apiKey, apiSecret) + if err != nil { + return nil, err } - if apiKey == "" { - return nil, errors.New("invalid cachefly api key") - } - - if apiSecret == "" { - return nil, errors.New("invalid cachefly api secret") - } - - client := cfsdk.NewClient(serverUrl, apiKey, apiSecret) if skipTlsVerify { - client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}) + client.SetTLSConfig(&tls.Config{InsecureSkipVerify: true}) } return client, nil diff --git a/internal/pkg/core/deployer/providers/dogecloud-cdn/dogecloud_cdn.go b/internal/pkg/core/deployer/providers/dogecloud-cdn/dogecloud_cdn.go index 9401285f..1c5e650e 100644 --- a/internal/pkg/core/deployer/providers/dogecloud-cdn/dogecloud_cdn.go +++ b/internal/pkg/core/deployer/providers/dogecloud-cdn/dogecloud_cdn.go @@ -35,7 +35,10 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) { panic("config is nil") } - client := dogesdk.NewClient(config.AccessKey, config.SecretKey) + client, err := createSdkClient(config.AccessKey, config.SecretKey) + if err != nil { + return nil, fmt.Errorf("failed to create sdk client: %w", err) + } uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{ AccessKey: config.AccessKey, @@ -64,6 +67,10 @@ func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer { } func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPEM string) (*deployer.DeployResult, error) { + if d.config.Domain == "" { + return nil, fmt.Errorf("config `domain` is required") + } + // 上传证书到 CDN upres, err := d.sslUploader.Upload(ctx, certPEM, privkeyPEM) if err != nil { @@ -75,11 +82,19 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE // 绑定证书 // REF: https://docs.dogecloud.com/cdn/api-cert-bind bindCdnCertId, _ := strconv.ParseInt(upres.CertId, 10, 64) - bindCdnCertResp, err := d.sdkClient.BindCdnCertWithDomain(bindCdnCertId, d.config.Domain) - d.logger.Debug("sdk request 'cdn.BindCdnCert'", slog.Int64("request.certId", bindCdnCertId), slog.String("request.domain", d.config.Domain), slog.Any("response", bindCdnCertResp)) + bindCdnCertReq := &dogesdk.BindCdnCertRequest{ + CertId: bindCdnCertId, + Domain: d.config.Domain, + } + bindCdnCertResp, err := d.sdkClient.BindCdnCert(bindCdnCertReq) + d.logger.Debug("sdk request 'cdn.BindCdnCert'", slog.Any("request", bindCdnCertReq), slog.Any("response", bindCdnCertResp)) if err != nil { return nil, fmt.Errorf("failed to execute sdk request 'cdn.BindCdnCert': %w", err) } return &deployer.DeployResult{}, nil } + +func createSdkClient(accessKey, secretKey string) (*dogesdk.Client, error) { + return dogesdk.NewClient(accessKey, secretKey) +} diff --git a/internal/pkg/core/deployer/providers/flexcdn/flexcdn.go b/internal/pkg/core/deployer/providers/flexcdn/flexcdn.go index 63db84b9..0a977d54 100644 --- a/internal/pkg/core/deployer/providers/flexcdn/flexcdn.go +++ b/internal/pkg/core/deployer/providers/flexcdn/flexcdn.go @@ -7,7 +7,6 @@ import ( "errors" "fmt" "log/slog" - "net/url" "time" "github.com/usual2970/certimate/internal/pkg/core/deployer" @@ -120,25 +119,13 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri } func createSdkClient(serverUrl, apiRole, accessKeyId, accessKey string, skipTlsVerify bool) (*flexcdnsdk.Client, error) { - if _, err := url.Parse(serverUrl); err != nil { - return nil, errors.New("invalid flexcdn server url") + client, err := flexcdnsdk.NewClient(serverUrl, apiRole, accessKeyId, accessKey) + if err != nil { + return nil, err } - if apiRole != "user" && apiRole != "admin" { - return nil, errors.New("invalid flexcdn api role") - } - - if accessKeyId == "" { - return nil, errors.New("invalid flexcdn access key id") - } - - if accessKey == "" { - return nil, errors.New("invalid flexcdn access key") - } - - client := flexcdnsdk.NewClient(serverUrl, apiRole, accessKeyId, accessKey) if skipTlsVerify { - client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}) + client.SetTLSConfig(&tls.Config{InsecureSkipVerify: true}) } return client, nil diff --git a/internal/pkg/core/deployer/providers/gcore-cdn/gcore_cdn.go b/internal/pkg/core/deployer/providers/gcore-cdn/gcore_cdn.go index 0d652df9..88feb79e 100644 --- a/internal/pkg/core/deployer/providers/gcore-cdn/gcore_cdn.go +++ b/internal/pkg/core/deployer/providers/gcore-cdn/gcore_cdn.go @@ -15,7 +15,7 @@ import ( "github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/uploader" uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/gcore-cdn" - gcoresdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/gcore/common" + gcoresdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/gcore" ) type DeployerConfig struct { diff --git a/internal/pkg/core/deployer/providers/goedge/goedge.go b/internal/pkg/core/deployer/providers/goedge/goedge.go index d17dfbfa..2457293e 100644 --- a/internal/pkg/core/deployer/providers/goedge/goedge.go +++ b/internal/pkg/core/deployer/providers/goedge/goedge.go @@ -7,7 +7,6 @@ import ( "errors" "fmt" "log/slog" - "net/url" "time" "github.com/usual2970/certimate/internal/pkg/core/deployer" @@ -120,25 +119,13 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri } func createSdkClient(serverUrl, apiRole, accessKeyId, accessKey string, skipTlsVerify bool) (*goedgesdk.Client, error) { - if _, err := url.Parse(serverUrl); err != nil { - return nil, errors.New("invalid goedge server url") + client, err := goedgesdk.NewClient(serverUrl, apiRole, accessKeyId, accessKey) + if err != nil { + return nil, err } - if apiRole != "user" && apiRole != "admin" { - return nil, errors.New("invalid goedge api role") - } - - if accessKeyId == "" { - return nil, errors.New("invalid goedge access key id") - } - - if accessKey == "" { - return nil, errors.New("invalid goedge access key") - } - - client := goedgesdk.NewClient(serverUrl, apiRole, accessKeyId, accessKey) if skipTlsVerify { - client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}) + client.SetTLSConfig(&tls.Config{InsecureSkipVerify: true}) } return client, nil diff --git a/internal/pkg/core/deployer/providers/lecdn/lecdn.go b/internal/pkg/core/deployer/providers/lecdn/lecdn.go index 4d9f4302..accfc0e7 100644 --- a/internal/pkg/core/deployer/providers/lecdn/lecdn.go +++ b/internal/pkg/core/deployer/providers/lecdn/lecdn.go @@ -6,12 +6,11 @@ import ( "errors" "fmt" "log/slog" - "net/url" "time" "github.com/usual2970/certimate/internal/pkg/core/deployer" - leclientsdkv3 "github.com/usual2970/certimate/internal/pkg/sdk3rd/lecdn/v3/client" - lemastersdkv3 "github.com/usual2970/certimate/internal/pkg/sdk3rd/lecdn/v3/master" + leclientsdkv3 "github.com/usual2970/certimate/internal/pkg/sdk3rd/lecdn/client-v3" + lemastersdkv3 "github.com/usual2970/certimate/internal/pkg/sdk3rd/lecdn/master-v3" ) type DeployerConfig struct { @@ -42,18 +41,11 @@ type DeployerConfig struct { type DeployerProvider struct { config *DeployerConfig logger *slog.Logger - sdkClient interface{} + sdkClient any } var _ deployer.Deployer = (*DeployerProvider)(nil) -const ( - apiVersionV3 = "v3" - - apiRoleClient = "client" - apiRoleMaster = "master" -) - func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) { if config == nil { panic("config is nil") @@ -104,34 +96,38 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri // REF: https://wdk0pwf8ul.feishu.cn/wiki/YE1XwCRIHiLYeKkPupgcXrlgnDd switch sdkClient := d.sdkClient.(type) { case *leclientsdkv3.Client: - updateSSLCertReq := &leclientsdkv3.UpdateCertificateRequest{ - Name: fmt.Sprintf("certimate-%d", time.Now().UnixMilli()), - Description: "upload from certimate", - Type: "upload", - SSLPEM: certPEM, - SSLKey: privkeyPEM, - AutoRenewal: false, - } - updateSSLCertResp, err := sdkClient.UpdateCertificate(d.config.CertificateId, updateSSLCertReq) - d.logger.Debug("sdk request 'lecdn.UpdateCertificate'", slog.Int64("certId", d.config.CertificateId), slog.Any("request", updateSSLCertReq), slog.Any("response", updateSSLCertResp)) - if err != nil { - return fmt.Errorf("failed to execute sdk request 'lecdn.UpdateCertificate': %w", err) + { + updateSSLCertReq := &leclientsdkv3.UpdateCertificateRequest{ + Name: fmt.Sprintf("certimate-%d", time.Now().UnixMilli()), + Description: "upload from certimate", + Type: "upload", + SSLPEM: certPEM, + SSLKey: privkeyPEM, + AutoRenewal: false, + } + updateSSLCertResp, err := sdkClient.UpdateCertificate(d.config.CertificateId, updateSSLCertReq) + d.logger.Debug("sdk request 'lecdn.UpdateCertificate'", slog.Int64("certId", d.config.CertificateId), slog.Any("request", updateSSLCertReq), slog.Any("response", updateSSLCertResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request 'lecdn.UpdateCertificate': %w", err) + } } case *lemastersdkv3.Client: - updateSSLCertReq := &lemastersdkv3.UpdateCertificateRequest{ - ClientId: d.config.ClientId, - Name: fmt.Sprintf("certimate-%d", time.Now().UnixMilli()), - Description: "upload from certimate", - Type: "upload", - SSLPEM: certPEM, - SSLKey: privkeyPEM, - AutoRenewal: false, - } - updateSSLCertResp, err := sdkClient.UpdateCertificate(d.config.CertificateId, updateSSLCertReq) - d.logger.Debug("sdk request 'lecdn.UpdateCertificate'", slog.Int64("certId", d.config.CertificateId), slog.Any("request", updateSSLCertReq), slog.Any("response", updateSSLCertResp)) - if err != nil { - return fmt.Errorf("failed to execute sdk request 'lecdn.UpdateCertificate': %w", err) + { + updateSSLCertReq := &lemastersdkv3.UpdateCertificateRequest{ + ClientId: d.config.ClientId, + Name: fmt.Sprintf("certimate-%d", time.Now().UnixMilli()), + Description: "upload from certimate", + Type: "upload", + SSLPEM: certPEM, + SSLKey: privkeyPEM, + AutoRenewal: false, + } + updateSSLCertResp, err := sdkClient.UpdateCertificate(d.config.CertificateId, updateSSLCertReq) + d.logger.Debug("sdk request 'lecdn.UpdateCertificate'", slog.Int64("certId", d.config.CertificateId), slog.Any("request", updateSSLCertReq), slog.Any("response", updateSSLCertResp)) + if err != nil { + return fmt.Errorf("failed to execute sdk request 'lecdn.UpdateCertificate': %w", err) + } } default: @@ -141,32 +137,35 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri return nil } -func createSdkClient(serverUrl, apiVersion, apiRole, username, password string, skipTlsVerify bool) (interface{}, error) { - if _, err := url.Parse(serverUrl); err != nil { - return nil, errors.New("invalid lecdn server url") - } +const ( + sdkVersionV3 = "v3" - if username == "" { - return nil, errors.New("invalid lecdn username") - } + sdkRoleClient = "client" + sdkRoleMaster = "master" +) - if password == "" { - return nil, errors.New("invalid lecdn password") - } - - if apiVersion == apiVersionV3 && apiRole == apiRoleClient { +func createSdkClient(serverUrl, apiVersion, apiRole, username, password string, skipTlsVerify bool) (any, error) { + if apiVersion == sdkVersionV3 && apiRole == sdkRoleClient { // v3 版客户端 - client := leclientsdkv3.NewClient(serverUrl, username, password) + client, err := leclientsdkv3.NewClient(serverUrl, username, password) + if err != nil { + return nil, err + } + if skipTlsVerify { - client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}) + client.SetTLSConfig(&tls.Config{InsecureSkipVerify: true}) } return client, nil - } else if apiVersion == apiVersionV3 && apiRole == apiRoleMaster { + } else if apiVersion == sdkVersionV3 && apiRole == sdkRoleMaster { // v3 版主控端 - client := lemastersdkv3.NewClient(serverUrl, username, password) + client, err := lemastersdkv3.NewClient(serverUrl, username, password) + if err != nil { + return nil, err + } + if skipTlsVerify { - client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}) + client.SetTLSConfig(&tls.Config{InsecureSkipVerify: true}) } return client, nil diff --git a/internal/pkg/core/deployer/providers/netlify-site/netlify_site.go b/internal/pkg/core/deployer/providers/netlify-site/netlify_site.go index 9a68505e..e45df168 100644 --- a/internal/pkg/core/deployer/providers/netlify-site/netlify_site.go +++ b/internal/pkg/core/deployer/providers/netlify-site/netlify_site.go @@ -80,10 +80,5 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE } func createSdkClient(apiToken string) (*netlifysdk.Client, error) { - if apiToken == "" { - return nil, errors.New("invalid netlify api token") - } - - client := netlifysdk.NewClient(apiToken) - return client, nil + return netlifysdk.NewClient(apiToken) } diff --git a/internal/pkg/core/deployer/providers/netlify-site/netlify_site_test.go b/internal/pkg/core/deployer/providers/netlify-site/netlify_site_test.go index eb4a447c..e693c1a3 100644 --- a/internal/pkg/core/deployer/providers/netlify-site/netlify_site_test.go +++ b/internal/pkg/core/deployer/providers/netlify-site/netlify_site_test.go @@ -15,7 +15,7 @@ var ( fInputCertPath string fInputKeyPath string fApiToken string - fSiteId int64 + fSiteId string ) func init() { @@ -24,7 +24,7 @@ func init() { flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "") flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "") flag.StringVar(&fApiToken, argsPrefix+"APITOKEN", "", "") - flag.Int64Var(&fSiteId, argsPrefix+"SITEID", 0, "") + flag.StringVar(&fSiteId, argsPrefix+"SITEID", "", "") } /* diff --git a/internal/pkg/core/deployer/providers/qiniu-cdn/qiniu_cdn.go b/internal/pkg/core/deployer/providers/qiniu-cdn/qiniu_cdn.go index 8491ecc3..6df43dfc 100644 --- a/internal/pkg/core/deployer/providers/qiniu-cdn/qiniu_cdn.go +++ b/internal/pkg/core/deployer/providers/qiniu-cdn/qiniu_cdn.go @@ -26,7 +26,7 @@ type DeployerConfig struct { type DeployerProvider struct { config *DeployerConfig logger *slog.Logger - sdkClient *qiniusdk.Client + sdkClient *qiniusdk.CdnManager sslUploader uploader.Uploader } @@ -37,7 +37,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) { panic("config is nil") } - client := qiniusdk.NewClient(auth.New(config.AccessKey, config.SecretKey)) + client := qiniusdk.NewCdnManager(auth.New(config.AccessKey, config.SecretKey)) uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{ AccessKey: config.AccessKey, diff --git a/internal/pkg/core/deployer/providers/rainyun-rcdn/rainyun_rcdn.go b/internal/pkg/core/deployer/providers/rainyun-rcdn/rainyun_rcdn.go index 99321f82..c4e603fd 100644 --- a/internal/pkg/core/deployer/providers/rainyun-rcdn/rainyun_rcdn.go +++ b/internal/pkg/core/deployer/providers/rainyun-rcdn/rainyun_rcdn.go @@ -2,7 +2,6 @@ package rainyunrcdn import ( "context" - "errors" "fmt" "log/slog" "strconv" @@ -92,10 +91,5 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE } func createSdkClient(apiKey string) (*rainyunsdk.Client, error) { - if apiKey == "" { - return nil, errors.New("invalid rainyun api key") - } - - client := rainyunsdk.NewClient(apiKey) - return client, nil + return rainyunsdk.NewClient(apiKey) } diff --git a/internal/pkg/core/deployer/providers/rainyun-rcdn/rainyun_rcdn_test.go b/internal/pkg/core/deployer/providers/rainyun-rcdn/rainyun_rcdn_test.go index fd81bffa..7c3d145f 100644 --- a/internal/pkg/core/deployer/providers/rainyun-rcdn/rainyun_rcdn_test.go +++ b/internal/pkg/core/deployer/providers/rainyun-rcdn/rainyun_rcdn_test.go @@ -53,8 +53,8 @@ func TestDeploy(t *testing.T) { }, "\n")) deployer, err := provider.NewDeployer(&provider.DeployerConfig{ - PrivateKey: fApiKey, - InstanceId: fInstanceId, + ApiKey: fApiKey, + InstanceId: int32(fInstanceId), Domain: fDomain, }) if err != nil { diff --git a/internal/pkg/core/deployer/providers/ratpanel-console/ratpanel_console.go b/internal/pkg/core/deployer/providers/ratpanel-console/ratpanel_console.go index 85e7f530..47de7c65 100644 --- a/internal/pkg/core/deployer/providers/ratpanel-console/ratpanel_console.go +++ b/internal/pkg/core/deployer/providers/ratpanel-console/ratpanel_console.go @@ -3,10 +3,8 @@ package ratpanelconsole import ( "context" "crypto/tls" - "errors" "fmt" "log/slog" - "net/url" "github.com/usual2970/certimate/internal/pkg/core/deployer" rpsdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/ratpanel" @@ -59,35 +57,27 @@ func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer { func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPEM string) (*deployer.DeployResult, error) { // 设置面板 SSL 证书 - settingCertReq := &rpsdk.SettingCertRequest{ + setSettingCertReq := &rpsdk.SetSettingCertRequest{ Certificate: certPEM, PrivateKey: privkeyPEM, } - settingCertResp, err := d.sdkClient.SettingCert(settingCertReq) - d.logger.Debug("sdk request 'ratpanel.SettingCert'", slog.Any("request", settingCertReq), slog.Any("response", settingCertResp)) + setSettingCertResp, err := d.sdkClient.SetSettingCert(setSettingCertReq) + d.logger.Debug("sdk request 'ratpanel.SetSettingCert'", slog.Any("request", setSettingCertReq), slog.Any("response", setSettingCertResp)) if err != nil { - return nil, fmt.Errorf("failed to execute sdk request 'ratpanel.SettingCert': %w", err) + return nil, fmt.Errorf("failed to execute sdk request 'ratpanel.SetSettingCert': %w", err) } return &deployer.DeployResult{}, nil } func createSdkClient(serverUrl string, accessTokenId int32, accessToken string, skipTlsVerify bool) (*rpsdk.Client, error) { - if _, err := url.Parse(serverUrl); err != nil { - return nil, errors.New("invalid ratpanel server url") + client, err := rpsdk.NewClient(serverUrl, accessTokenId, accessToken) + if err != nil { + return nil, err } - if accessTokenId == 0 { - return nil, errors.New("invalid ratpanel access token id") - } - - if accessToken == "" { - return nil, errors.New("invalid ratpanel access token") - } - - client := rpsdk.NewClient(serverUrl, accessTokenId, accessToken) if skipTlsVerify { - client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}) + client.SetTLSConfig(&tls.Config{InsecureSkipVerify: true}) } return client, nil diff --git a/internal/pkg/core/deployer/providers/ratpanel-site/ratpanel_site.go b/internal/pkg/core/deployer/providers/ratpanel-site/ratpanel_site.go index 7e30daf6..f7e01218 100644 --- a/internal/pkg/core/deployer/providers/ratpanel-site/ratpanel_site.go +++ b/internal/pkg/core/deployer/providers/ratpanel-site/ratpanel_site.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "log/slog" - "net/url" "github.com/usual2970/certimate/internal/pkg/core/deployer" rpsdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/ratpanel" @@ -65,36 +64,28 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE } // 设置站点 SSL 证书 - websiteCertReq := &rpsdk.WebsiteCertRequest{ + setWebsiteCertReq := &rpsdk.SetWebsiteCertRequest{ SiteName: d.config.SiteName, Certificate: certPEM, PrivateKey: privkeyPEM, } - websiteCertResp, err := d.sdkClient.WebsiteCert(websiteCertReq) - d.logger.Debug("sdk request 'ratpanel.WebsiteCert'", slog.Any("request", websiteCertReq), slog.Any("response", websiteCertResp)) + setWebsiteCertResp, err := d.sdkClient.SetWebsiteCert(setWebsiteCertReq) + d.logger.Debug("sdk request 'ratpanel.SetWebsiteCert'", slog.Any("request", setWebsiteCertReq), slog.Any("response", setWebsiteCertResp)) if err != nil { - return nil, fmt.Errorf("failed to execute sdk request 'ratpanel.WebsiteCert': %w", err) + return nil, fmt.Errorf("failed to execute sdk request 'ratpanel.SetWebsiteCert': %w", err) } return &deployer.DeployResult{}, nil } func createSdkClient(serverUrl string, accessTokenId int32, accessToken string, skipTlsVerify bool) (*rpsdk.Client, error) { - if _, err := url.Parse(serverUrl); err != nil { - return nil, errors.New("invalid ratpanel server url") + client, err := rpsdk.NewClient(serverUrl, accessTokenId, accessToken) + if err != nil { + return nil, err } - if accessTokenId == 0 { - return nil, errors.New("invalid ratpanel access token id") - } - - if accessToken == "" { - return nil, errors.New("invalid ratpanel access token") - } - - client := rpsdk.NewClient(serverUrl, accessTokenId, accessToken) if skipTlsVerify { - client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}) + client.SetTLSConfig(&tls.Config{InsecureSkipVerify: true}) } return client, nil diff --git a/internal/pkg/core/deployer/providers/safeline/safeline.go b/internal/pkg/core/deployer/providers/safeline/safeline.go index 253a8754..ac7ac5e0 100644 --- a/internal/pkg/core/deployer/providers/safeline/safeline.go +++ b/internal/pkg/core/deployer/providers/safeline/safeline.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "log/slog" - "net/url" "github.com/usual2970/certimate/internal/pkg/core/deployer" safelinesdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/safeline" @@ -84,7 +83,7 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri updateCertificateReq := &safelinesdk.UpdateCertificateRequest{ Id: d.config.CertificateId, Type: 2, - Manual: &safelinesdk.UpdateCertificateRequestBodyManul{ + Manual: &safelinesdk.CertificateManul{ Crt: certPEM, Key: privkeyPEM, }, @@ -99,17 +98,13 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri } func createSdkClient(serverUrl, apiToken string, skipTlsVerify bool) (*safelinesdk.Client, error) { - if _, err := url.Parse(serverUrl); err != nil { - return nil, errors.New("invalid safeline server url") + client, err := safelinesdk.NewClient(serverUrl, apiToken) + if err != nil { + return nil, err } - if apiToken == "" { - return nil, errors.New("invalid safeline api token") - } - - client := safelinesdk.NewClient(serverUrl, apiToken) if skipTlsVerify { - client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}) + client.SetTLSConfig(&tls.Config{InsecureSkipVerify: true}) } return client, nil diff --git a/internal/pkg/core/deployer/providers/tencentcloud-gaap/tencentcloud_gaap_test.go b/internal/pkg/core/deployer/providers/tencentcloud-gaap/tencentcloud_gaap_test.go index 32943362..d25d3a9a 100644 --- a/internal/pkg/core/deployer/providers/tencentcloud-gaap/tencentcloud_gaap_test.go +++ b/internal/pkg/core/deployer/providers/tencentcloud-gaap/tencentcloud_gaap_test.go @@ -16,7 +16,6 @@ var ( fInputKeyPath string fSecretId string fSecretKey string - fProxyGroupId string fProxyId string fListenerId string ) @@ -28,7 +27,6 @@ func init() { flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "") flag.StringVar(&fSecretId, argsPrefix+"SECRETID", "", "") flag.StringVar(&fSecretKey, argsPrefix+"SECRETKEY", "", "") - flag.StringVar(&fProxyGroupId, argsPrefix+"PROXYGROUPID", "", "") flag.StringVar(&fProxyId, argsPrefix+"PROXYID", "", "") flag.StringVar(&fListenerId, argsPrefix+"LISTENERID", "", "") } @@ -41,7 +39,6 @@ Shell command to run this test: --CERTIMATE_DEPLOYER_TENCENTCLOUDGAAP_INPUTKEYPATH="/path/to/your-input-key.pem" \ --CERTIMATE_DEPLOYER_TENCENTCLOUDGAAP_SECRETID="your-secret-id" \ --CERTIMATE_DEPLOYER_TENCENTCLOUDGAAP_SECRETKEY="your-secret-key" \ - --CERTIMATE_DEPLOYER_TENCENTCLOUDGAAP_PROXYGROUPID="your-gaap-group-id" \ --CERTIMATE_DEPLOYER_TENCENTCLOUDGAAP_PROXYID="your-gaap-group-id" \ --CERTIMATE_DEPLOYER_TENCENTCLOUDGAAP_LISTENERID="your-clb-listener-id" */ @@ -55,7 +52,6 @@ func TestDeploy(t *testing.T) { fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath), fmt.Sprintf("SECRETID: %v", fSecretId), fmt.Sprintf("SECRETKEY: %v", fSecretKey), - fmt.Sprintf("PROXYGROUPID: %v", fProxyGroupId), fmt.Sprintf("PROXYID: %v", fProxyId), fmt.Sprintf("LISTENERID: %v", fListenerId), }, "\n")) @@ -64,7 +60,6 @@ func TestDeploy(t *testing.T) { SecretId: fSecretId, SecretKey: fSecretKey, ResourceType: provider.RESOURCE_TYPE_LISTENER, - ProxyGroupId: fProxyGroupId, ProxyId: fProxyId, ListenerId: fListenerId, }) diff --git a/internal/pkg/core/deployer/providers/unicloud-webhost/unicloud_webhost.go b/internal/pkg/core/deployer/providers/unicloud-webhost/unicloud_webhost.go index 82946bf1..cd62cb35 100644 --- a/internal/pkg/core/deployer/providers/unicloud-webhost/unicloud_webhost.go +++ b/internal/pkg/core/deployer/providers/unicloud-webhost/unicloud_webhost.go @@ -88,14 +88,5 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE } func createSdkClient(username, password string) (*unisdk.Client, error) { - if username == "" { - return nil, errors.New("invalid unicloud username") - } - - if password == "" { - return nil, errors.New("invalid unicloud password") - } - - client := unisdk.NewClient(username, password) - return client, nil + return unisdk.NewClient(username, password) } diff --git a/internal/pkg/core/deployer/providers/upyun-cdn/upyun_cdn.go b/internal/pkg/core/deployer/providers/upyun-cdn/upyun_cdn.go index 2fbe52b8..b558f9ae 100644 --- a/internal/pkg/core/deployer/providers/upyun-cdn/upyun_cdn.go +++ b/internal/pkg/core/deployer/providers/upyun-cdn/upyun_cdn.go @@ -2,7 +2,6 @@ package upyuncdn import ( "context" - "errors" "fmt" "log/slog" @@ -116,14 +115,5 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE } func createSdkClient(username, password string) (*upyunsdk.Client, error) { - if username == "" { - return nil, errors.New("invalid upyun username") - } - - if password == "" { - return nil, errors.New("invalid upyun password") - } - - client := upyunsdk.NewClient(username, password) - return client, nil + return upyunsdk.NewClient(username, password) } diff --git a/internal/pkg/core/deployer/providers/wangsu-cdn/wangsu_cdn.go b/internal/pkg/core/deployer/providers/wangsu-cdn/wangsu_cdn.go index fc33165f..3c2925dd 100644 --- a/internal/pkg/core/deployer/providers/wangsu-cdn/wangsu_cdn.go +++ b/internal/pkg/core/deployer/providers/wangsu-cdn/wangsu_cdn.go @@ -2,7 +2,6 @@ package wangsucdn import ( "context" - "errors" "fmt" "log/slog" "strconv" @@ -97,13 +96,5 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE } func createSdkClient(accessKeyId, accessKeySecret string) (*wangsusdk.Client, error) { - if accessKeyId == "" { - return nil, errors.New("invalid wangsu access key id") - } - - if accessKeySecret == "" { - return nil, errors.New("invalid wangsu access key secret") - } - - return wangsusdk.NewClient(accessKeyId, accessKeySecret), nil + return wangsusdk.NewClient(accessKeyId, accessKeySecret) } diff --git a/internal/pkg/core/deployer/providers/wangsu-cdnpro/wangsu_cdnpro.go b/internal/pkg/core/deployer/providers/wangsu-cdnpro/wangsu_cdnpro.go index e706fe26..48dedf06 100644 --- a/internal/pkg/core/deployer/providers/wangsu-cdnpro/wangsu_cdnpro.go +++ b/internal/pkg/core/deployer/providers/wangsu-cdnpro/wangsu_cdnpro.go @@ -98,7 +98,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE if err != nil { return nil, fmt.Errorf("failed to encrypt private key: %w", err) } - certificateNewVersionInfo := &wangsucdn.CertificateVersion{ + certificateNewVersionInfo := &wangsucdn.CertificateVersionInfo{ PrivateKey: xtypes.ToPtr(encryptedPrivateKey), Certificate: xtypes.ToPtr(certPEM), IdentificationInfo: &wangsucdn.CertificateVersionIdentificationInfo{ @@ -131,7 +131,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE return nil, fmt.Errorf("failed to execute sdk request 'cdnpro.CreateCertificate': %w", err) } - wangsuCertUrl = createCertificateResp.CertificateUrl + wangsuCertUrl = createCertificateResp.CertificateLocation d.logger.Info("ssl certificate uploaded", slog.Any("certUrl", wangsuCertUrl)) wangsuCertIdMatches := regexp.MustCompile(`/certificates/([a-zA-Z0-9-]+)`).FindStringSubmatch(wangsuCertUrl) @@ -154,7 +154,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE return nil, fmt.Errorf("failed to execute sdk request 'cdnpro.UpdateCertificate': %w", err) } - wangsuCertUrl = updateCertificateResp.CertificateUrl + wangsuCertUrl = updateCertificateResp.CertificateLocation d.logger.Info("ssl certificate uploaded", slog.Any("certUrl", wangsuCertUrl)) wangsuCertIdMatches := regexp.MustCompile(`/certificates/([a-zA-Z0-9-]+)`).FindStringSubmatch(wangsuCertUrl) @@ -174,7 +174,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE createDeploymentTaskReq := &wangsucdn.CreateDeploymentTaskRequest{ Name: xtypes.ToPtr(fmt.Sprintf("certimate_%d", time.Now().UnixMilli())), Target: xtypes.ToPtr(d.config.Environment), - Actions: &[]wangsucdn.DeploymentTaskAction{ + Actions: &[]wangsucdn.DeploymentTaskActionInfo{ { Action: xtypes.ToPtr("deploy_cert"), CertificateId: xtypes.ToPtr(wangsuCertId), @@ -194,7 +194,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE // 循环获取部署任务详细信息,等待任务状态变更 // REF: https://www.wangsu.com/document/api-doc/27038 var wangsuTaskId string - wangsuTaskMatches := regexp.MustCompile(`/deploymentTasks/([a-zA-Z0-9-]+)`).FindStringSubmatch(createDeploymentTaskResp.DeploymentTaskUrl) + wangsuTaskMatches := regexp.MustCompile(`/deploymentTasks/([a-zA-Z0-9-]+)`).FindStringSubmatch(createDeploymentTaskResp.DeploymentTaskLocation) if len(wangsuTaskMatches) > 1 { wangsuTaskId = wangsuTaskMatches[1] } @@ -225,15 +225,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE } func createSdkClient(accessKeyId, accessKeySecret string) (*wangsucdn.Client, error) { - if accessKeyId == "" { - return nil, errors.New("invalid wangsu access key id") - } - - if accessKeySecret == "" { - return nil, errors.New("invalid wangsu access key secret") - } - - return wangsucdn.NewClient(accessKeyId, accessKeySecret), nil + return wangsucdn.NewClient(accessKeyId, accessKeySecret) } func encryptPrivateKey(privkeyPEM string, apiKey string, timestamp int64) (string, error) { diff --git a/internal/pkg/core/deployer/providers/wangsu-certificate/wangsu_certificate.go b/internal/pkg/core/deployer/providers/wangsu-certificate/wangsu_certificate.go index ae9ce84f..69e9edf0 100644 --- a/internal/pkg/core/deployer/providers/wangsu-certificate/wangsu_certificate.go +++ b/internal/pkg/core/deployer/providers/wangsu-certificate/wangsu_certificate.go @@ -2,7 +2,6 @@ package wangsucertificate import ( "context" - "errors" "fmt" "log/slog" "time" @@ -97,13 +96,5 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE } func createSdkClient(accessKeyId, accessKeySecret string) (*wangsusdk.Client, error) { - if accessKeyId == "" { - return nil, errors.New("invalid wangsu access key id") - } - - if accessKeySecret == "" { - return nil, errors.New("invalid wangsu access key secret") - } - - return wangsusdk.NewClient(accessKeyId, accessKeySecret), nil + return wangsusdk.NewClient(accessKeyId, accessKeySecret) } diff --git a/internal/pkg/core/notifier/providers/discordbot/discordbot_test.go b/internal/pkg/core/notifier/providers/discordbot/discordbot_test.go index 42edf95e..39a63bfa 100644 --- a/internal/pkg/core/notifier/providers/discordbot/discordbot_test.go +++ b/internal/pkg/core/notifier/providers/discordbot/discordbot_test.go @@ -24,7 +24,7 @@ func init() { argsPrefix := "CERTIMATE_NOTIFIER_DISCORDBOT_" flag.StringVar(&fApiToken, argsPrefix+"APITOKEN", "", "") - flag.StringVar(&fChannelId, argsPrefix+"CHANNELID", 0, "") + flag.StringVar(&fChannelId, argsPrefix+"CHANNELID", "", "") } /* diff --git a/internal/pkg/core/notifier/providers/slackbot/slackbot_test.go b/internal/pkg/core/notifier/providers/slackbot/slackbot_test.go index 356ef71f..688daa6a 100644 --- a/internal/pkg/core/notifier/providers/slackbot/slackbot_test.go +++ b/internal/pkg/core/notifier/providers/slackbot/slackbot_test.go @@ -24,7 +24,7 @@ func init() { argsPrefix := "CERTIMATE_NOTIFIER_SLACKBOT_" flag.StringVar(&fApiToken, argsPrefix+"APITOKEN", "", "") - flag.StringVar(&fChannelId, argsPrefix+"CHANNELID", 0, "") + flag.StringVar(&fChannelId, argsPrefix+"CHANNELID", "", "") } /* diff --git a/internal/pkg/core/uploader/providers/1panel-ssl/1panel_ssl.go b/internal/pkg/core/uploader/providers/1panel-ssl/1panel_ssl.go index 77ce16f0..8eeabd86 100644 --- a/internal/pkg/core/uploader/providers/1panel-ssl/1panel_ssl.go +++ b/internal/pkg/core/uploader/providers/1panel-ssl/1panel_ssl.go @@ -3,15 +3,14 @@ package onepanelssl import ( "context" "crypto/tls" - "errors" "fmt" "log/slog" - "net/url" "strings" "time" "github.com/usual2970/certimate/internal/pkg/core/uploader" onepanelsdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/1panel" + onepanelsdkv2 "github.com/usual2970/certimate/internal/pkg/sdk3rd/1panel/v2" ) type UploaderConfig struct { @@ -28,7 +27,7 @@ type UploaderConfig struct { type UploaderProvider struct { config *UploaderConfig logger *slog.Logger - sdkClient *onepanelsdk.Client + sdkClient any } var _ uploader.Uploader = (*UploaderProvider)(nil) @@ -72,23 +71,46 @@ func (u *UploaderProvider) Upload(ctx context.Context, certPEM string, privkeyPE certName := fmt.Sprintf("certimate-%d", time.Now().UnixMilli()) // 上传证书 - uploadWebsiteSSLReq := &onepanelsdk.UploadWebsiteSSLRequest{ - Type: "paste", - Description: certName, - Certificate: certPEM, - PrivateKey: privkeyPEM, - } - uploadWebsiteSSLResp, err := u.sdkClient.UploadWebsiteSSL(uploadWebsiteSSLReq) - u.logger.Debug("sdk request '1panel.UploadWebsiteSSL'", slog.Any("request", uploadWebsiteSSLReq), slog.Any("response", uploadWebsiteSSLResp)) - if err != nil { - return nil, fmt.Errorf("failed to execute sdk request '1panel.UploadWebsiteSSL': %w", err) + switch sdkClient := u.sdkClient.(type) { + case *onepanelsdk.Client: + { + uploadWebsiteSSLReq := &onepanelsdk.UploadWebsiteSSLRequest{ + Type: "paste", + Description: certName, + Certificate: certPEM, + PrivateKey: privkeyPEM, + } + uploadWebsiteSSLResp, err := sdkClient.UploadWebsiteSSL(uploadWebsiteSSLReq) + u.logger.Debug("sdk request '1panel.UploadWebsiteSSL'", slog.Any("request", uploadWebsiteSSLReq), slog.Any("response", uploadWebsiteSSLResp)) + if err != nil { + return nil, fmt.Errorf("failed to execute sdk request '1panel.UploadWebsiteSSL': %w", err) + } + } + + case *onepanelsdkv2.Client: + { + uploadWebsiteSSLReq := &onepanelsdkv2.UploadWebsiteSSLRequest{ + Type: "paste", + Description: certName, + Certificate: certPEM, + PrivateKey: privkeyPEM, + } + uploadWebsiteSSLResp, err := sdkClient.UploadWebsiteSSL(uploadWebsiteSSLReq) + u.logger.Debug("sdk request '1panel.UploadWebsiteSSL'", slog.Any("request", uploadWebsiteSSLReq), slog.Any("response", uploadWebsiteSSLResp)) + if err != nil { + return nil, fmt.Errorf("failed to execute sdk request '1panel.UploadWebsiteSSL': %w", err) + } + } + + default: + panic("sdk client is not implemented") } // 遍历证书列表,获取刚刚上传证书 ID if res, err := u.findCertIfExists(ctx, certPEM, privkeyPEM); err != nil { return nil, err } else if res == nil { - return nil, fmt.Errorf("no ssl certificate found, may be upload failed (code: %d, message: %s)", uploadWebsiteSSLResp.GetCode(), uploadWebsiteSSLResp.GetMessage()) + return nil, fmt.Errorf("no ssl certificate found, may be upload failed") } else { return res, nil } @@ -97,6 +119,7 @@ func (u *UploaderProvider) Upload(ctx context.Context, certPEM string, privkeyPE func (u *UploaderProvider) findCertIfExists(ctx context.Context, certPEM string, privkeyPEM string) (*uploader.UploadResult, error) { searchWebsiteSSLPageNumber := int32(1) searchWebsiteSSLPageSize := int32(100) + searchWebsiteSSLItemsCount := int32(0) for { select { case <-ctx.Done(): @@ -104,28 +127,68 @@ func (u *UploaderProvider) findCertIfExists(ctx context.Context, certPEM string, default: } - searchWebsiteSSLReq := &onepanelsdk.SearchWebsiteSSLRequest{ - Page: searchWebsiteSSLPageNumber, - PageSize: searchWebsiteSSLPageSize, - } - searchWebsiteSSLResp, err := u.sdkClient.SearchWebsiteSSL(searchWebsiteSSLReq) - u.logger.Debug("sdk request '1panel.SearchWebsiteSSL'", slog.Any("request", searchWebsiteSSLReq), slog.Any("response", searchWebsiteSSLResp)) - if err != nil { - return nil, fmt.Errorf("failed to execute sdk request '1panel.SearchWebsiteSSL': %w", err) - } + switch sdkClient := u.sdkClient.(type) { + case *onepanelsdk.Client: + { + searchWebsiteSSLReq := &onepanelsdk.SearchWebsiteSSLRequest{ + Page: searchWebsiteSSLPageNumber, + PageSize: searchWebsiteSSLPageSize, + } + searchWebsiteSSLResp, err := sdkClient.SearchWebsiteSSL(searchWebsiteSSLReq) + u.logger.Debug("sdk request '1panel.SearchWebsiteSSL'", slog.Any("request", searchWebsiteSSLReq), slog.Any("response", searchWebsiteSSLResp)) + if err != nil { + return nil, fmt.Errorf("failed to execute sdk request '1panel.SearchWebsiteSSL': %w", err) + } - for _, sslItem := range searchWebsiteSSLResp.Data.Items { - if strings.TrimSpace(sslItem.PEM) == strings.TrimSpace(certPEM) && - strings.TrimSpace(sslItem.PrivateKey) == strings.TrimSpace(privkeyPEM) { - // 如果已存在相同证书,直接返回 - return &uploader.UploadResult{ - CertId: fmt.Sprintf("%d", sslItem.ID), - CertName: sslItem.Description, - }, nil + if searchWebsiteSSLResp.Data != nil { + for _, sslItem := range searchWebsiteSSLResp.Data.Items { + if strings.TrimSpace(sslItem.PEM) == strings.TrimSpace(certPEM) && + strings.TrimSpace(sslItem.PrivateKey) == strings.TrimSpace(privkeyPEM) { + // 如果已存在相同证书,直接返回 + return &uploader.UploadResult{ + CertId: fmt.Sprintf("%d", sslItem.ID), + CertName: sslItem.Description, + }, nil + } + } + } + + searchWebsiteSSLItemsCount = searchWebsiteSSLResp.Data.Total } + + case *onepanelsdkv2.Client: + { + searchWebsiteSSLReq := &onepanelsdkv2.SearchWebsiteSSLRequest{ + Page: searchWebsiteSSLPageNumber, + PageSize: searchWebsiteSSLPageSize, + } + searchWebsiteSSLResp, err := sdkClient.SearchWebsiteSSL(searchWebsiteSSLReq) + u.logger.Debug("sdk request '1panel.SearchWebsiteSSL'", slog.Any("request", searchWebsiteSSLReq), slog.Any("response", searchWebsiteSSLResp)) + if err != nil { + return nil, fmt.Errorf("failed to execute sdk request '1panel.SearchWebsiteSSL': %w", err) + } + + if searchWebsiteSSLResp.Data != nil { + for _, sslItem := range searchWebsiteSSLResp.Data.Items { + if strings.TrimSpace(sslItem.PEM) == strings.TrimSpace(certPEM) && + strings.TrimSpace(sslItem.PrivateKey) == strings.TrimSpace(privkeyPEM) { + // 如果已存在相同证书,直接返回 + return &uploader.UploadResult{ + CertId: fmt.Sprintf("%d", sslItem.ID), + CertName: sslItem.Description, + }, nil + } + } + } + + searchWebsiteSSLItemsCount = searchWebsiteSSLResp.Data.Total + } + + default: + panic("sdk client is not implemented") } - if len(searchWebsiteSSLResp.Data.Items) < int(searchWebsiteSSLPageSize) { + if searchWebsiteSSLItemsCount < searchWebsiteSSLPageSize { break } else { searchWebsiteSSLPageNumber++ @@ -135,23 +198,35 @@ func (u *UploaderProvider) findCertIfExists(ctx context.Context, certPEM string, return nil, nil } -func createSdkClient(serverUrl, apiVersion, apiKey string, skipTlsVerify bool) (*onepanelsdk.Client, error) { - if _, err := url.Parse(serverUrl); err != nil { - return nil, errors.New("invalid 1panel server url") +const ( + sdkVersionV1 = "v1" + sdkVersionV2 = "v2" +) + +func createSdkClient(serverUrl, apiVersion, apiKey string, skipTlsVerify bool) (any, error) { + if apiVersion == sdkVersionV1 { + client, err := onepanelsdk.NewClient(serverUrl, apiKey) + if err != nil { + return nil, err + } + + if skipTlsVerify { + client.SetTLSConfig(&tls.Config{InsecureSkipVerify: true}) + } + + return client, nil + } else if apiVersion == sdkVersionV2 { + client, err := onepanelsdkv2.NewClient(serverUrl, apiKey) + if err != nil { + return nil, err + } + + if skipTlsVerify { + client.SetTLSConfig(&tls.Config{InsecureSkipVerify: true}) + } + + return client, nil } - if apiVersion == "" { - return nil, errors.New("invalid 1panel api version") - } - - if apiKey == "" { - return nil, errors.New("invalid 1panel api key") - } - - client := onepanelsdk.NewClient(serverUrl, apiVersion, apiKey) - if skipTlsVerify { - client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}) - } - - return client, nil + return nil, fmt.Errorf("invalid 1panel api version") } diff --git a/internal/pkg/core/uploader/providers/azure-keyvault/azure_keyvault.go b/internal/pkg/core/uploader/providers/azure-keyvault/azure_keyvault.go index f299d29e..c6387146 100644 --- a/internal/pkg/core/uploader/providers/azure-keyvault/azure_keyvault.go +++ b/internal/pkg/core/uploader/providers/azure-keyvault/azure_keyvault.go @@ -14,7 +14,7 @@ import ( "github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azcertificates" "github.com/usual2970/certimate/internal/pkg/core/uploader" - azcommon "github.com/usual2970/certimate/internal/pkg/sdk3rd/azure/common" + azenv "github.com/usual2970/certimate/internal/pkg/sdk3rd/azure/env" xcert "github.com/usual2970/certimate/internal/pkg/utils/cert" ) @@ -176,7 +176,7 @@ func (u *UploaderProvider) Upload(ctx context.Context, certPEM string, privkeyPE } func createSdkClient(tenantId, clientId, clientSecret, cloudName, keyvaultName string) (*azcertificates.Client, error) { - env, err := azcommon.GetCloudEnvironmentConfiguration(cloudName) + env, err := azenv.GetCloudEnvConfiguration(cloudName) if err != nil { return nil, err } @@ -189,9 +189,9 @@ func createSdkClient(tenantId, clientId, clientSecret, cloudName, keyvaultName s } endpoint := fmt.Sprintf("https://%s.vault.azure.net", keyvaultName) - if azcommon.IsEnvironmentGovernment(cloudName) { + if azenv.IsUSGovernmentEnv(cloudName) { endpoint = fmt.Sprintf("https://%s.vault.usgovcloudapi.net", keyvaultName) - } else if azcommon.IsEnvironmentChina(cloudName) { + } else if azenv.IsChinaEnv(cloudName) { endpoint = fmt.Sprintf("https://%s.vault.azure.cn", keyvaultName) } diff --git a/internal/pkg/core/uploader/providers/dogecloud/dogecloud.go b/internal/pkg/core/uploader/providers/dogecloud/dogecloud.go index 1b0b963f..4670e354 100644 --- a/internal/pkg/core/uploader/providers/dogecloud/dogecloud.go +++ b/internal/pkg/core/uploader/providers/dogecloud/dogecloud.go @@ -58,8 +58,13 @@ func (u *UploaderProvider) Upload(ctx context.Context, certPEM string, privkeyPE // 上传新证书 // REF: https://docs.dogecloud.com/cdn/api-cert-upload - uploadSslCertResp, err := u.sdkClient.UploadCdnCert(certName, certPEM, privkeyPEM) - u.logger.Debug("sdk request 'cdn.UploadCdnCert'", slog.Any("response", uploadSslCertResp)) + uploadSslCertReq := &dogesdk.UploadCdnCertRequest{ + Note: certName, + Certificate: certPEM, + PrivateKey: privkeyPEM, + } + uploadSslCertResp, err := u.sdkClient.UploadCdnCert(uploadSslCertReq) + u.logger.Debug("sdk request 'cdn.UploadCdnCert'", slog.Any("request", uploadSslCertReq), slog.Any("response", uploadSslCertResp)) if err != nil { return nil, fmt.Errorf("failed to execute sdk request 'cdn.UploadCdnCert': %w", err) } @@ -72,6 +77,5 @@ func (u *UploaderProvider) Upload(ctx context.Context, certPEM string, privkeyPE } func createSdkClient(accessKey, secretKey string) (*dogesdk.Client, error) { - client := dogesdk.NewClient(accessKey, secretKey) - return client, nil + return dogesdk.NewClient(accessKey, secretKey) } diff --git a/internal/pkg/core/uploader/providers/gcore-cdn/gcore_cdn.go b/internal/pkg/core/uploader/providers/gcore-cdn/gcore_cdn.go index f3127602..86a4c314 100644 --- a/internal/pkg/core/uploader/providers/gcore-cdn/gcore_cdn.go +++ b/internal/pkg/core/uploader/providers/gcore-cdn/gcore_cdn.go @@ -11,7 +11,7 @@ import ( "github.com/G-Core/gcorelabscdn-go/sslcerts" "github.com/usual2970/certimate/internal/pkg/core/uploader" - gcoresdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/gcore/common" + gcoresdk "github.com/usual2970/certimate/internal/pkg/sdk3rd/gcore" ) type UploaderConfig struct { diff --git a/internal/pkg/core/uploader/providers/qiniu-sslcert/qiniu_sslcert.go b/internal/pkg/core/uploader/providers/qiniu-sslcert/qiniu_sslcert.go index abd0787b..a6f18e5e 100644 --- a/internal/pkg/core/uploader/providers/qiniu-sslcert/qiniu_sslcert.go +++ b/internal/pkg/core/uploader/providers/qiniu-sslcert/qiniu_sslcert.go @@ -24,7 +24,7 @@ type UploaderConfig struct { type UploaderProvider struct { config *UploaderConfig logger *slog.Logger - sdkClient *qiniusdk.Client + sdkClient *qiniusdk.CdnManager } var _ uploader.Uploader = (*UploaderProvider)(nil) @@ -81,7 +81,7 @@ func (u *UploaderProvider) Upload(ctx context.Context, certPEM string, privkeyPE }, nil } -func createSdkClient(accessKey, secretKey string) (*qiniusdk.Client, error) { +func createSdkClient(accessKey, secretKey string) (*qiniusdk.CdnManager, error) { if secretKey == "" { return nil, errors.New("invalid qiniu access key") } @@ -91,6 +91,6 @@ func createSdkClient(accessKey, secretKey string) (*qiniusdk.Client, error) { } credential := auth.New(accessKey, secretKey) - client := qiniusdk.NewClient(credential) + client := qiniusdk.NewCdnManager(credential) return client, nil } diff --git a/internal/pkg/core/uploader/providers/rainyun-sslcenter/rainyun_sslcenter.go b/internal/pkg/core/uploader/providers/rainyun-sslcenter/rainyun_sslcenter.go index 765e0af7..02234795 100644 --- a/internal/pkg/core/uploader/providers/rainyun-sslcenter/rainyun_sslcenter.go +++ b/internal/pkg/core/uploader/providers/rainyun-sslcenter/rainyun_sslcenter.go @@ -76,7 +76,7 @@ func (u *UploaderProvider) Upload(ctx context.Context, certPEM string, privkeyPE if res, err := u.findCertIfExists(ctx, certPEM); err != nil { return nil, err } else if res == nil { - return nil, errors.New("rainyun sslcenter: no certificate found") + return nil, errors.New("no ssl certificate found, may be upload failed") } else { return res, nil } @@ -166,10 +166,5 @@ func (u *UploaderProvider) findCertIfExists(ctx context.Context, certPEM string) } func createSdkClient(apiKey string) (*rainyunsdk.Client, error) { - if apiKey == "" { - return nil, errors.New("invalid rainyun api key") - } - - client := rainyunsdk.NewClient(apiKey) - return client, nil + return rainyunsdk.NewClient(apiKey) } diff --git a/internal/pkg/core/uploader/providers/upyun-ssl/upyun_ssl.go b/internal/pkg/core/uploader/providers/upyun-ssl/upyun_ssl.go index 6b45e130..57e8e506 100644 --- a/internal/pkg/core/uploader/providers/upyun-ssl/upyun_ssl.go +++ b/internal/pkg/core/uploader/providers/upyun-ssl/upyun_ssl.go @@ -2,7 +2,6 @@ package upyunssl import ( "context" - "errors" "fmt" "log/slog" @@ -69,14 +68,5 @@ func (u *UploaderProvider) Upload(ctx context.Context, certPEM string, privkeyPE } func createSdkClient(username, password string) (*upyunsdk.Client, error) { - if username == "" { - return nil, errors.New("invalid upyun username") - } - - if password == "" { - return nil, errors.New("invalid upyun password") - } - - client := upyunsdk.NewClient(username, password) - return client, nil + return upyunsdk.NewClient(username, password) } diff --git a/internal/pkg/core/uploader/providers/wangsu-certificate/wangsu_certificate.go b/internal/pkg/core/uploader/providers/wangsu-certificate/wangsu_certificate.go index 97c64ae0..3f2c6824 100644 --- a/internal/pkg/core/uploader/providers/wangsu-certificate/wangsu_certificate.go +++ b/internal/pkg/core/uploader/providers/wangsu-certificate/wangsu_certificate.go @@ -2,7 +2,6 @@ package wangsucertificate import ( "context" - "errors" "fmt" "log/slog" "regexp" @@ -116,7 +115,7 @@ func (u *UploaderProvider) Upload(ctx context.Context, certPEM string, privkeyPE // 网宿云证书 URL 中包含证书 ID // 格式: // https://open.chinanetcenter.com/api/certificate/100001 - wangsuCertIdMatches := regexp.MustCompile(`/certificate/([0-9]+)`).FindStringSubmatch(createCertificateResp.CertificateUrl) + wangsuCertIdMatches := regexp.MustCompile(`/certificate/([0-9]+)`).FindStringSubmatch(createCertificateResp.CertificateLocation) if len(wangsuCertIdMatches) > 1 { certId = wangsuCertIdMatches[1] } else { @@ -130,13 +129,5 @@ func (u *UploaderProvider) Upload(ctx context.Context, certPEM string, privkeyPE } func createSdkClient(accessKeyId, accessKeySecret string) (*wangsusdk.Client, error) { - if accessKeyId == "" { - return nil, errors.New("invalid wangsu access key id") - } - - if accessKeySecret == "" { - return nil, errors.New("invalid wangsu access key secret") - } - - return wangsusdk.NewClient(accessKeyId, accessKeySecret), nil + return wangsusdk.NewClient(accessKeyId, accessKeySecret) } diff --git a/internal/pkg/sdk3rd/1panel/api.go b/internal/pkg/sdk3rd/1panel/api.go deleted file mode 100644 index 91eff206..00000000 --- a/internal/pkg/sdk3rd/1panel/api.go +++ /dev/null @@ -1,60 +0,0 @@ -package onepanel - -import ( - "fmt" - "net/http" -) - -func (c *Client) UpdateSystemSSL(req *UpdateSystemSSLRequest) (*UpdateSystemSSLResponse, error) { - resp := &UpdateSystemSSLResponse{} - - path := "/settings/ssl/update" - if c.version == "v2" { - path = "/core" + path - } - - err := c.sendRequestWithResult(http.MethodPost, path, req, resp) - return resp, err -} - -func (c *Client) SearchWebsiteSSL(req *SearchWebsiteSSLRequest) (*SearchWebsiteSSLResponse, error) { - resp := &SearchWebsiteSSLResponse{} - err := c.sendRequestWithResult(http.MethodPost, "/websites/ssl/search", req, resp) - return resp, err -} - -func (c *Client) GetWebsiteSSL(req *GetWebsiteSSLRequest) (*GetWebsiteSSLResponse, error) { - if req.SSLID == 0 { - return nil, fmt.Errorf("1panel api error: invalid parameter: SSLID") - } - - resp := &GetWebsiteSSLResponse{} - err := c.sendRequestWithResult(http.MethodGet, fmt.Sprintf("/websites/ssl/%d", req.SSLID), req, resp) - return resp, err -} - -func (c *Client) UploadWebsiteSSL(req *UploadWebsiteSSLRequest) (*UploadWebsiteSSLResponse, error) { - resp := &UploadWebsiteSSLResponse{} - err := c.sendRequestWithResult(http.MethodPost, "/websites/ssl/upload", req, resp) - return resp, err -} - -func (c *Client) GetHttpsConf(req *GetHttpsConfRequest) (*GetHttpsConfResponse, error) { - if req.WebsiteID == 0 { - return nil, fmt.Errorf("1panel api error: invalid parameter: WebsiteID") - } - - resp := &GetHttpsConfResponse{} - err := c.sendRequestWithResult(http.MethodGet, fmt.Sprintf("/websites/%d/https", req.WebsiteID), req, resp) - return resp, err -} - -func (c *Client) UpdateHttpsConf(req *UpdateHttpsConfRequest) (*UpdateHttpsConfResponse, error) { - if req.WebsiteID == 0 { - return nil, fmt.Errorf("1panel api error: invalid parameter: WebsiteID") - } - - resp := &UpdateHttpsConfResponse{} - err := c.sendRequestWithResult(http.MethodPost, fmt.Sprintf("/websites/%d/https", req.WebsiteID), req, resp) - return resp, err -} diff --git a/internal/pkg/sdk3rd/1panel/api_get_https_conf.go b/internal/pkg/sdk3rd/1panel/api_get_https_conf.go new file mode 100644 index 00000000..4fd3a873 --- /dev/null +++ b/internal/pkg/sdk3rd/1panel/api_get_https_conf.go @@ -0,0 +1,43 @@ +package onepanel + +import ( + "context" + "fmt" + "net/http" +) + +type GetHttpsConfResponse struct { + apiResponseBase + + Data *struct { + Enable bool `json:"enable"` + HttpConfig string `json:"httpConfig"` + SSLProtocol []string `json:"SSLProtocol"` + Algorithm string `json:"algorithm"` + Hsts bool `json:"hsts"` + } `json:"data,omitempty"` +} + +func (c *Client) GetHttpsConf(websiteId int64) (*GetHttpsConfResponse, error) { + return c.GetHttpsConfWithContext(context.Background(), websiteId) +} + +func (c *Client) GetHttpsConfWithContext(ctx context.Context, websiteId int64) (*GetHttpsConfResponse, error) { + if websiteId == 0 { + return nil, fmt.Errorf("sdkerr: unset websiteId") + } + + httpreq, err := c.newRequest(http.MethodGet, fmt.Sprintf("/websites/%d/https", websiteId)) + if err != nil { + return nil, err + } else { + httpreq.SetContext(ctx) + } + + result := &GetHttpsConfResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/1panel/api_get_website_ssl.go b/internal/pkg/sdk3rd/1panel/api_get_website_ssl.go new file mode 100644 index 00000000..aeab2dab --- /dev/null +++ b/internal/pkg/sdk3rd/1panel/api_get_website_ssl.go @@ -0,0 +1,50 @@ +package onepanel + +import ( + "context" + "fmt" + "net/http" +) + +type GetWebsiteSSLResponse struct { + apiResponseBase + + Data *struct { + ID int64 `json:"id"` + Provider string `json:"provider"` + Description string `json:"description"` + PrimaryDomain string `json:"primaryDomain"` + Domains string `json:"domains"` + Type string `json:"type"` + Organization string `json:"organization"` + Status string `json:"status"` + StartDate string `json:"startDate"` + ExpireDate string `json:"expireDate"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` + } `json:"data,omitempty"` +} + +func (c *Client) GetWebsiteSSL(sslId int64) (*GetWebsiteSSLResponse, error) { + return c.GetWebsiteSSLWithContext(context.Background(), sslId) +} + +func (c *Client) GetWebsiteSSLWithContext(ctx context.Context, sslId int64) (*GetWebsiteSSLResponse, error) { + if sslId == 0 { + return nil, fmt.Errorf("sdkerr: unset sslId") + } + + httpreq, err := c.newRequest(http.MethodGet, fmt.Sprintf("/websites/ssl/%d", sslId)) + if err != nil { + return nil, err + } else { + httpreq.SetContext(ctx) + } + + result := &GetWebsiteSSLResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/1panel/api_search_website_ssl.go b/internal/pkg/sdk3rd/1panel/api_search_website_ssl.go new file mode 100644 index 00000000..10ceb366 --- /dev/null +++ b/internal/pkg/sdk3rd/1panel/api_search_website_ssl.go @@ -0,0 +1,50 @@ +package onepanel + +import ( + "context" + "net/http" +) + +type SearchWebsiteSSLRequest struct { + Page int32 `json:"page"` + PageSize int32 `json:"pageSize"` +} + +type SearchWebsiteSSLResponse struct { + apiResponseBase + + Data *struct { + Items []*struct { + ID int64 `json:"id"` + PEM string `json:"pem"` + PrivateKey string `json:"privateKey"` + Domains string `json:"domains"` + Description string `json:"description"` + Status string `json:"status"` + UpdatedAt string `json:"updatedAt"` + CreatedAt string `json:"createdAt"` + } `json:"items"` + Total int32 `json:"total"` + } `json:"data,omitempty"` +} + +func (c *Client) SearchWebsiteSSL(req *SearchWebsiteSSLRequest) (*SearchWebsiteSSLResponse, error) { + return c.SearchWebsiteSSLWithContext(context.Background(), req) +} + +func (c *Client) SearchWebsiteSSLWithContext(ctx context.Context, req *SearchWebsiteSSLRequest) (*SearchWebsiteSSLResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/websites/ssl/search") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &SearchWebsiteSSLResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/1panel/api_update_https_conf.go b/internal/pkg/sdk3rd/1panel/api_update_https_conf.go new file mode 100644 index 00000000..ba79fd68 --- /dev/null +++ b/internal/pkg/sdk3rd/1panel/api_update_https_conf.go @@ -0,0 +1,53 @@ +package onepanel + +import ( + "context" + "fmt" + "net/http" +) + +type UpdateHttpsConfRequest struct { + WebsiteID int64 `json:"websiteId"` + Enable bool `json:"enable"` + Type string `json:"type"` + WebsiteSSLID int64 `json:"websiteSSLId"` + PrivateKey string `json:"privateKey"` + Certificate string `json:"certificate"` + PrivateKeyPath string `json:"privateKeyPath"` + CertificatePath string `json:"certificatePath"` + ImportType string `json:"importType"` + HttpConfig string `json:"httpConfig"` + SSLProtocol []string `json:"SSLProtocol"` + Algorithm string `json:"algorithm"` + Hsts bool `json:"hsts"` +} + +type UpdateHttpsConfResponse struct { + apiResponseBase +} + +func (c *Client) UpdateHttpsConf(websiteId int64, req *UpdateHttpsConfRequest) (*UpdateHttpsConfResponse, error) { + return c.UpdateHttpsConfWithContext(context.Background(), websiteId, req) +} + +func (c *Client) UpdateHttpsConfWithContext(ctx context.Context, websiteId int64, req *UpdateHttpsConfRequest) (*UpdateHttpsConfResponse, error) { + if websiteId == 0 { + return nil, fmt.Errorf("sdkerr: unset websiteId") + } + + httpreq, err := c.newRequest(http.MethodPost, fmt.Sprintf("/websites/%d/https", websiteId)) + if err != nil { + return nil, err + } else { + req.WebsiteID = websiteId + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &UpdateHttpsConfResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/1panel/api_update_settings_ssl.go b/internal/pkg/sdk3rd/1panel/api_update_settings_ssl.go new file mode 100644 index 00000000..055472b0 --- /dev/null +++ b/internal/pkg/sdk3rd/1panel/api_update_settings_ssl.go @@ -0,0 +1,40 @@ +package onepanel + +import ( + "context" + "net/http" +) + +type UpdateSettingsSSLRequest struct { + Cert string `json:"cert"` + Key string `json:"key"` + SSLType string `json:"sslType"` + SSL string `json:"ssl"` + SSLID int64 `json:"sslID"` + AutoRestart string `json:"autoRestart"` +} + +type UpdateSettingsSSLResponse struct { + apiResponseBase +} + +func (c *Client) UpdateSettingsSSL(req *UpdateSettingsSSLRequest) (*UpdateSettingsSSLResponse, error) { + return c.UpdateSettingsSSLWithContext(context.Background(), req) +} + +func (c *Client) UpdateSettingsSSLWithContext(ctx context.Context, req *UpdateSettingsSSLRequest) (*UpdateSettingsSSLResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/settings/ssl/update") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &UpdateSettingsSSLResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/1panel/api_upload_website_ssl.go b/internal/pkg/sdk3rd/1panel/api_upload_website_ssl.go new file mode 100644 index 00000000..160ac40c --- /dev/null +++ b/internal/pkg/sdk3rd/1panel/api_upload_website_ssl.go @@ -0,0 +1,41 @@ +package onepanel + +import ( + "context" + "net/http" +) + +type UploadWebsiteSSLRequest struct { + SSLID int64 `json:"sslID"` + Type string `json:"type"` + Certificate string `json:"certificate"` + CertificatePath string `json:"certificatePath"` + PrivateKey string `json:"privateKey"` + PrivateKeyPath string `json:"privateKeyPath"` + Description string `json:"description"` +} + +type UploadWebsiteSSLResponse struct { + apiResponseBase +} + +func (c *Client) UploadWebsiteSSL(req *UploadWebsiteSSLRequest) (*UploadWebsiteSSLResponse, error) { + return c.UploadWebsiteSSLWithContext(context.Background(), req) +} + +func (c *Client) UploadWebsiteSSLWithContext(ctx context.Context, req *UploadWebsiteSSLRequest) (*UploadWebsiteSSLResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/websites/ssl/upload") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &UploadWebsiteSSLResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/1panel/client.go b/internal/pkg/sdk3rd/1panel/client.go index 5d9acb6d..5f52ce9a 100644 --- a/internal/pkg/sdk3rd/1panel/client.go +++ b/internal/pkg/sdk3rd/1panel/client.go @@ -7,6 +7,7 @@ import ( "encoding/json" "fmt" "net/http" + "net/url" "strings" "time" @@ -14,17 +15,24 @@ import ( ) type Client struct { - client *resty.Client - version string + client *resty.Client } -func NewClient(serverUrl, apiVersion, apiKey string) *Client { - if apiVersion == "" { - apiVersion = "v1" +func NewClient(serverUrl, apiKey string) (*Client, error) { + if serverUrl == "" { + return nil, fmt.Errorf("sdkerr: unset serverUrl") + } + if _, err := url.Parse(serverUrl); err != nil { + return nil, fmt.Errorf("sdkerr: invalid serverUrl: %w", err) + } + if apiKey == "" { + return nil, fmt.Errorf("sdkerr: unset apiKey") } client := resty.New(). - SetBaseURL(strings.TrimRight(serverUrl, "/")+"/api/"+apiVersion). + SetBaseURL(strings.TrimRight(serverUrl, "/")+"/api/v1"). + SetHeader("Accept", "application/json"). + SetHeader("Content-Type", "application/json"). SetHeader("User-Agent", "certimate"). SetPreRequestHook(func(c *resty.Client, req *http.Request) error { timestamp := fmt.Sprintf("%d", time.Now().Unix()) @@ -36,66 +44,73 @@ func NewClient(serverUrl, apiVersion, apiKey string) *Client { return nil }) - return &Client{ - client: client, - version: apiVersion, - } + return &Client{client}, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { +func (c *Client) SetTimeout(timeout time.Duration) *Client { c.client.SetTimeout(timeout) return c } -func (c *Client) WithTLSConfig(config *tls.Config) *Client { +func (c *Client) SetTLSConfig(config *tls.Config) *Client { c.client.SetTLSClientConfig(config) return c } -func (c *Client) sendRequest(method string, path string, params interface{}) (*resty.Response, error) { - req := c.client.R() - if strings.EqualFold(method, http.MethodGet) { - qs := make(map[string]string) - if params != nil { - temp := make(map[string]any) - jsonb, _ := json.Marshal(params) - json.Unmarshal(jsonb, &temp) - for k, v := range temp { - if v != nil { - qs[k] = fmt.Sprintf("%v", v) - } - } - } - - req = req.SetQueryParams(qs) - } else { - req = req.SetHeader("Content-Type", "application/json").SetBody(params) +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") } - resp, err := req.Execute(method, path) + req := c.client.R() + req.Method = method + req.URL = path + return req, nil +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + // WARN: + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. + + resp, err := req.Send() if err != nil { - return resp, fmt.Errorf("1panel api error: failed to send request: %w", err) + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) } else if resp.IsError() { - return resp, fmt.Errorf("1panel api error: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) } return resp, nil } -func (c *Client) sendRequestWithResult(method string, path string, params interface{}, result BaseResponse) error { - resp, err := c.sendRequest(method, path, params) +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + resp, err := c.doRequest(req) if err != nil { if resp != nil { - json.Unmarshal(resp.Body(), &result) + json.Unmarshal(resp.Body(), &res) } - return err + return resp, err } - if err := json.Unmarshal(resp.Body(), &result); err != nil { - return fmt.Errorf("1panel api error: failed to unmarshal response: %w", err) - } else if errcode := result.GetCode(); errcode/100 != 2 { - return fmt.Errorf("1panel api error: code='%d', message='%s'", errcode, result.GetMessage()) + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) + } else { + if tcode := res.GetCode(); tcode/100 != 2 { + return resp, fmt.Errorf("sdkerr: api error: code='%d', message='%s'", tcode, res.GetMessage()) + } + } } - return nil + return resp, nil } diff --git a/internal/pkg/sdk3rd/1panel/models.go b/internal/pkg/sdk3rd/1panel/models.go deleted file mode 100644 index 57ea5154..00000000 --- a/internal/pkg/sdk3rd/1panel/models.go +++ /dev/null @@ -1,131 +0,0 @@ -package onepanel - -type BaseResponse interface { - GetCode() int32 - GetMessage() string -} - -type baseResponse struct { - Code *int32 `json:"code,omitempty"` - Message *string `json:"message,omitempty"` -} - -func (r *baseResponse) GetCode() int32 { - if r.Code != nil { - return *r.Code - } - return 0 -} - -func (r *baseResponse) GetMessage() string { - if r.Message != nil { - return *r.Message - } - return "" -} - -type UpdateSystemSSLRequest struct { - Cert string `json:"cert"` - Key string `json:"key"` - SSLType string `json:"sslType"` - SSL string `json:"ssl"` - SSLID int64 `json:"sslID"` - AutoRestart string `json:"autoRestart"` -} - -type UpdateSystemSSLResponse struct { - baseResponse -} - -type SearchWebsiteSSLRequest struct { - Page int32 `json:"page"` - PageSize int32 `json:"pageSize"` -} - -type SearchWebsiteSSLResponse struct { - baseResponse - Data *struct { - Items []*struct { - ID int64 `json:"id"` - PEM string `json:"pem"` - PrivateKey string `json:"privateKey"` - Domains string `json:"domains"` - Description string `json:"description"` - Status string `json:"status"` - UpdatedAt string `json:"updatedAt"` - CreatedAt string `json:"createdAt"` - } `json:"items"` - Total int32 `json:"total"` - } `json:"data,omitempty"` -} - -type GetWebsiteSSLRequest struct { - SSLID int64 `json:"-"` -} - -type GetWebsiteSSLResponse struct { - baseResponse - Data *struct { - ID int64 `json:"id"` - Provider string `json:"provider"` - Description string `json:"description"` - PrimaryDomain string `json:"primaryDomain"` - Domains string `json:"domains"` - Type string `json:"type"` - Organization string `json:"organization"` - Status string `json:"status"` - StartDate string `json:"startDate"` - ExpireDate string `json:"expireDate"` - CreatedAt string `json:"createdAt"` - UpdatedAt string `json:"updatedAt"` - } `json:"data,omitempty"` -} - -type UploadWebsiteSSLRequest struct { - Type string `json:"type"` - SSLID int64 `json:"sslID"` - Certificate string `json:"certificate"` - CertificatePath string `json:"certificatePath"` - PrivateKey string `json:"privateKey"` - PrivateKeyPath string `json:"privateKeyPath"` - Description string `json:"description"` -} - -type UploadWebsiteSSLResponse struct { - baseResponse -} - -type GetHttpsConfRequest struct { - WebsiteID int64 `json:"-"` -} - -type GetHttpsConfResponse struct { - baseResponse - Data *struct { - Enable bool `json:"enable"` - HttpConfig string `json:"httpConfig"` - SSLProtocol []string `json:"SSLProtocol"` - Algorithm string `json:"algorithm"` - Hsts bool `json:"hsts"` - } `json:"data,omitempty"` -} - -type UpdateHttpsConfRequest struct { - WebsiteID int64 `json:"websiteId"` - Enable bool `json:"enable"` - Type string `json:"type"` - WebsiteSSLID int64 `json:"websiteSSLId"` - PrivateKey string `json:"privateKey"` - Certificate string `json:"certificate"` - PrivateKeyPath string `json:"privateKeyPath"` - CertificatePath string `json:"certificatePath"` - ImportType string `json:"importType"` - HttpConfig string `json:"httpConfig"` - SSLProtocol []string `json:"SSLProtocol"` - Algorithm string `json:"algorithm"` - Hsts bool `json:"hsts"` -} - -type UpdateHttpsConfResponse struct { - baseResponse -} diff --git a/internal/pkg/sdk3rd/1panel/types.go b/internal/pkg/sdk3rd/1panel/types.go new file mode 100644 index 00000000..c8398b02 --- /dev/null +++ b/internal/pkg/sdk3rd/1panel/types.go @@ -0,0 +1,29 @@ +package onepanel + +type apiResponse interface { + GetCode() int32 + GetMessage() string +} + +type apiResponseBase struct { + Code *int32 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` +} + +func (r *apiResponseBase) GetCode() int32 { + if r.Code == nil { + return 0 + } + + return *r.Code +} + +func (r *apiResponseBase) GetMessage() string { + if r.Message == nil { + return "" + } + + return *r.Message +} + +var _ apiResponse = (*apiResponseBase)(nil) diff --git a/internal/pkg/sdk3rd/1panel/v2/api_get_https_conf.go b/internal/pkg/sdk3rd/1panel/v2/api_get_https_conf.go new file mode 100644 index 00000000..c20ea650 --- /dev/null +++ b/internal/pkg/sdk3rd/1panel/v2/api_get_https_conf.go @@ -0,0 +1,43 @@ +package onepanelv2 + +import ( + "context" + "fmt" + "net/http" +) + +type GetHttpsConfResponse struct { + apiResponseBase + + Data *struct { + Enable bool `json:"enable"` + HttpConfig string `json:"httpConfig"` + SSLProtocol []string `json:"SSLProtocol"` + Algorithm string `json:"algorithm"` + Hsts bool `json:"hsts"` + } `json:"data,omitempty"` +} + +func (c *Client) GetHttpsConf(websiteId int64) (*GetHttpsConfResponse, error) { + return c.GetHttpsConfWithContext(context.Background(), websiteId) +} + +func (c *Client) GetHttpsConfWithContext(ctx context.Context, websiteId int64) (*GetHttpsConfResponse, error) { + if websiteId == 0 { + return nil, fmt.Errorf("sdkerr: unset websiteId") + } + + httpreq, err := c.newRequest(http.MethodGet, fmt.Sprintf("/websites/%d/https", websiteId)) + if err != nil { + return nil, err + } else { + httpreq.SetContext(ctx) + } + + result := &GetHttpsConfResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/1panel/v2/api_get_website_ssl.go b/internal/pkg/sdk3rd/1panel/v2/api_get_website_ssl.go new file mode 100644 index 00000000..c3d4be3a --- /dev/null +++ b/internal/pkg/sdk3rd/1panel/v2/api_get_website_ssl.go @@ -0,0 +1,50 @@ +package onepanelv2 + +import ( + "context" + "fmt" + "net/http" +) + +type GetWebsiteSSLResponse struct { + apiResponseBase + + Data *struct { + ID int64 `json:"id"` + Provider string `json:"provider"` + Description string `json:"description"` + PrimaryDomain string `json:"primaryDomain"` + Domains string `json:"domains"` + Type string `json:"type"` + Organization string `json:"organization"` + Status string `json:"status"` + StartDate string `json:"startDate"` + ExpireDate string `json:"expireDate"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` + } `json:"data,omitempty"` +} + +func (c *Client) GetWebsiteSSL(sslId int64) (*GetWebsiteSSLResponse, error) { + return c.GetWebsiteSSLWithContext(context.Background(), sslId) +} + +func (c *Client) GetWebsiteSSLWithContext(ctx context.Context, sslId int64) (*GetWebsiteSSLResponse, error) { + if sslId == 0 { + return nil, fmt.Errorf("sdkerr: unset sslId") + } + + httpreq, err := c.newRequest(http.MethodGet, fmt.Sprintf("/websites/ssl/%d", sslId)) + if err != nil { + return nil, err + } else { + httpreq.SetContext(ctx) + } + + result := &GetWebsiteSSLResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/1panel/v2/api_search_website_ssl.go b/internal/pkg/sdk3rd/1panel/v2/api_search_website_ssl.go new file mode 100644 index 00000000..c46a301a --- /dev/null +++ b/internal/pkg/sdk3rd/1panel/v2/api_search_website_ssl.go @@ -0,0 +1,50 @@ +package onepanelv2 + +import ( + "context" + "net/http" +) + +type SearchWebsiteSSLRequest struct { + Page int32 `json:"page"` + PageSize int32 `json:"pageSize"` +} + +type SearchWebsiteSSLResponse struct { + apiResponseBase + + Data *struct { + Items []*struct { + ID int64 `json:"id"` + PEM string `json:"pem"` + PrivateKey string `json:"privateKey"` + Domains string `json:"domains"` + Description string `json:"description"` + Status string `json:"status"` + UpdatedAt string `json:"updatedAt"` + CreatedAt string `json:"createdAt"` + } `json:"items"` + Total int32 `json:"total"` + } `json:"data,omitempty"` +} + +func (c *Client) SearchWebsiteSSL(req *SearchWebsiteSSLRequest) (*SearchWebsiteSSLResponse, error) { + return c.SearchWebsiteSSLWithContext(context.Background(), req) +} + +func (c *Client) SearchWebsiteSSLWithContext(ctx context.Context, req *SearchWebsiteSSLRequest) (*SearchWebsiteSSLResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/websites/ssl/search") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &SearchWebsiteSSLResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/1panel/v2/api_update_core_settings_ssl.go b/internal/pkg/sdk3rd/1panel/v2/api_update_core_settings_ssl.go new file mode 100644 index 00000000..aa53fc6f --- /dev/null +++ b/internal/pkg/sdk3rd/1panel/v2/api_update_core_settings_ssl.go @@ -0,0 +1,40 @@ +package onepanelv2 + +import ( + "context" + "net/http" +) + +type UpdateCoreSettingsSSLRequest struct { + Cert string `json:"cert"` + Key string `json:"key"` + SSLType string `json:"sslType"` + SSL string `json:"ssl"` + SSLID int64 `json:"sslID"` + AutoRestart string `json:"autoRestart"` +} + +type UpdateCoreSettingsSSLResponse struct { + apiResponseBase +} + +func (c *Client) UpdateCoreSettingsSSL(req *UpdateCoreSettingsSSLRequest) (*UpdateCoreSettingsSSLResponse, error) { + return c.UpdateCoreSettingsSSLWithContext(context.Background(), req) +} + +func (c *Client) UpdateCoreSettingsSSLWithContext(ctx context.Context, req *UpdateCoreSettingsSSLRequest) (*UpdateCoreSettingsSSLResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/core/settings/ssl/update") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &UpdateCoreSettingsSSLResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/1panel/v2/api_update_https_conf.go b/internal/pkg/sdk3rd/1panel/v2/api_update_https_conf.go new file mode 100644 index 00000000..e4750613 --- /dev/null +++ b/internal/pkg/sdk3rd/1panel/v2/api_update_https_conf.go @@ -0,0 +1,53 @@ +package onepanelv2 + +import ( + "context" + "fmt" + "net/http" +) + +type UpdateHttpsConfRequest struct { + WebsiteID int64 `json:"websiteId"` + Enable bool `json:"enable"` + Type string `json:"type"` + WebsiteSSLID int64 `json:"websiteSSLId"` + PrivateKey string `json:"privateKey"` + Certificate string `json:"certificate"` + PrivateKeyPath string `json:"privateKeyPath"` + CertificatePath string `json:"certificatePath"` + ImportType string `json:"importType"` + HttpConfig string `json:"httpConfig"` + SSLProtocol []string `json:"SSLProtocol"` + Algorithm string `json:"algorithm"` + Hsts bool `json:"hsts"` +} + +type UpdateHttpsConfResponse struct { + apiResponseBase +} + +func (c *Client) UpdateHttpsConf(websiteId int64, req *UpdateHttpsConfRequest) (*UpdateHttpsConfResponse, error) { + return c.UpdateHttpsConfWithContext(context.Background(), websiteId, req) +} + +func (c *Client) UpdateHttpsConfWithContext(ctx context.Context, websiteId int64, req *UpdateHttpsConfRequest) (*UpdateHttpsConfResponse, error) { + if websiteId == 0 { + return nil, fmt.Errorf("sdkerr: unset websiteId") + } + + httpreq, err := c.newRequest(http.MethodPost, fmt.Sprintf("/websites/%d/https", websiteId)) + if err != nil { + return nil, err + } else { + req.WebsiteID = websiteId + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &UpdateHttpsConfResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/1panel/v2/api_upload_website_ssl.go b/internal/pkg/sdk3rd/1panel/v2/api_upload_website_ssl.go new file mode 100644 index 00000000..3ce50cdf --- /dev/null +++ b/internal/pkg/sdk3rd/1panel/v2/api_upload_website_ssl.go @@ -0,0 +1,41 @@ +package onepanelv2 + +import ( + "context" + "net/http" +) + +type UploadWebsiteSSLRequest struct { + SSLID int64 `json:"sslID"` + Type string `json:"type"` + Certificate string `json:"certificate"` + CertificatePath string `json:"certificatePath"` + PrivateKey string `json:"privateKey"` + PrivateKeyPath string `json:"privateKeyPath"` + Description string `json:"description"` +} + +type UploadWebsiteSSLResponse struct { + apiResponseBase +} + +func (c *Client) UploadWebsiteSSL(req *UploadWebsiteSSLRequest) (*UploadWebsiteSSLResponse, error) { + return c.UploadWebsiteSSLWithContext(context.Background(), req) +} + +func (c *Client) UploadWebsiteSSLWithContext(ctx context.Context, req *UploadWebsiteSSLRequest) (*UploadWebsiteSSLResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/websites/ssl/upload") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &UploadWebsiteSSLResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/1panel/v2/client.go b/internal/pkg/sdk3rd/1panel/v2/client.go new file mode 100644 index 00000000..3a74c5bf --- /dev/null +++ b/internal/pkg/sdk3rd/1panel/v2/client.go @@ -0,0 +1,116 @@ +package onepanelv2 + +import ( + "crypto/md5" + "crypto/tls" + "encoding/hex" + "encoding/json" + "fmt" + "net/http" + "net/url" + "strings" + "time" + + "github.com/go-resty/resty/v2" +) + +type Client struct { + client *resty.Client +} + +func NewClient(serverUrl, apiKey string) (*Client, error) { + if serverUrl == "" { + return nil, fmt.Errorf("sdkerr: unset serverUrl") + } + if _, err := url.Parse(serverUrl); err != nil { + return nil, fmt.Errorf("sdkerr: invalid serverUrl: %w", err) + } + if apiKey == "" { + return nil, fmt.Errorf("sdkerr: unset apiKey") + } + + client := resty.New(). + SetBaseURL(strings.TrimRight(serverUrl, "/")+"/api/v2"). + SetHeader("Accept", "application/json"). + SetHeader("Content-Type", "application/json"). + SetHeader("User-Agent", "certimate"). + SetPreRequestHook(func(c *resty.Client, req *http.Request) error { + timestamp := fmt.Sprintf("%d", time.Now().Unix()) + tokenMd5 := md5.Sum([]byte("1panel" + apiKey + timestamp)) + tokenMd5Hex := hex.EncodeToString(tokenMd5[:]) + req.Header.Set("1Panel-Timestamp", timestamp) + req.Header.Set("1Panel-Token", tokenMd5Hex) + + return nil + }) + + return &Client{client}, nil +} + +func (c *Client) SetTimeout(timeout time.Duration) *Client { + c.client.SetTimeout(timeout) + return c +} + +func (c *Client) SetTLSConfig(config *tls.Config) *Client { + c.client.SetTLSClientConfig(config) + return c +} + +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") + } + + req := c.client.R() + req.Method = method + req.URL = path + return req, nil +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + // WARN: + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. + + resp, err := req.Send() + if err != nil { + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) + } else if resp.IsError() { + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) + } + + return resp, nil +} + +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + resp, err := c.doRequest(req) + if err != nil { + if resp != nil { + json.Unmarshal(resp.Body(), &res) + } + return resp, err + } + + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) + } else { + if tcode := res.GetCode(); tcode/100 != 2 { + return resp, fmt.Errorf("sdkerr: api error: code='%d', message='%s'", tcode, res.GetMessage()) + } + } + } + + return resp, nil +} diff --git a/internal/pkg/sdk3rd/1panel/v2/types.go b/internal/pkg/sdk3rd/1panel/v2/types.go new file mode 100644 index 00000000..0d3f5108 --- /dev/null +++ b/internal/pkg/sdk3rd/1panel/v2/types.go @@ -0,0 +1,29 @@ +package onepanelv2 + +type apiResponse interface { + GetCode() int32 + GetMessage() string +} + +type apiResponseBase struct { + Code *int32 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` +} + +func (r *apiResponseBase) GetCode() int32 { + if r.Code == nil { + return 0 + } + + return *r.Code +} + +func (r *apiResponseBase) GetMessage() string { + if r.Message == nil { + return "" + } + + return *r.Message +} + +var _ apiResponse = (*apiResponseBase)(nil) diff --git a/internal/pkg/sdk3rd/apisix/api.go b/internal/pkg/sdk3rd/apisix/api.go deleted file mode 100644 index 7ebfba04..00000000 --- a/internal/pkg/sdk3rd/apisix/api.go +++ /dev/null @@ -1,16 +0,0 @@ -package apisix - -import ( - "fmt" - "net/http" -) - -func (c *Client) UpdateSSL(req *UpdateSSLRequest) (*UpdateSSLResponse, error) { - if req.ID == "" { - return nil, fmt.Errorf("1panel api error: invalid parameter: ID") - } - - resp := &UpdateSSLResponse{} - err := c.sendRequestWithResult(http.MethodGet, fmt.Sprintf("/ssls/%s", req.ID), req, resp) - return resp, err -} diff --git a/internal/pkg/sdk3rd/apisix/api_update_ssl.go b/internal/pkg/sdk3rd/apisix/api_update_ssl.go new file mode 100644 index 00000000..0894364d --- /dev/null +++ b/internal/pkg/sdk3rd/apisix/api_update_ssl.go @@ -0,0 +1,44 @@ +package apisix + +import ( + "context" + "fmt" + "net/http" +) + +type UpdateSSLRequest struct { + Cert *string `json:"cert,omitempty"` + Key *string `json:"key,omitempty"` + SNIs *[]string `json:"snis,omitempty"` + Type *string `json:"type,omitempty"` + Status *int32 `json:"status,omitempty"` +} + +type UpdateSSLResponse struct { + apiResponseBase +} + +func (c *Client) UpdateSSL(sslId string, req *UpdateSSLRequest) (*UpdateSSLResponse, error) { + return c.UpdateSSLWithContext(context.Background(), sslId, req) +} + +func (c *Client) UpdateSSLWithContext(ctx context.Context, sslId string, req *UpdateSSLRequest) (*UpdateSSLResponse, error) { + if sslId == "" { + return nil, fmt.Errorf("sdkerr: unset sslId") + } + + httpreq, err := c.newRequest(http.MethodPut, fmt.Sprintf("/ssls/%s", sslId)) + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &UpdateSSLResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/apisix/client.go b/internal/pkg/sdk3rd/apisix/client.go index 66784824..006a8f6e 100644 --- a/internal/pkg/sdk3rd/apisix/client.go +++ b/internal/pkg/sdk3rd/apisix/client.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "net/http" + "net/url" "strings" "time" @@ -15,9 +16,21 @@ type Client struct { client *resty.Client } -func NewClient(serverUrl, apiKey string) *Client { +func NewClient(serverUrl, apiKey string) (*Client, error) { + if serverUrl == "" { + return nil, fmt.Errorf("sdkerr: unset serverUrl") + } + if _, err := url.Parse(serverUrl); err != nil { + return nil, fmt.Errorf("sdkerr: invalid serverUrl: %w", err) + } + if apiKey == "" { + return nil, fmt.Errorf("sdkerr: unset apiKey") + } + client := resty.New(). SetBaseURL(strings.TrimRight(serverUrl, "/")+"/apisix/admin"). + SetHeader("Accept", "application/json"). + SetHeader("Content-Type", "application/json"). SetHeader("User-Agent", "certimate"). SetPreRequestHook(func(c *resty.Client, req *http.Request) error { req.Header.Set("X-API-KEY", apiKey) @@ -25,63 +38,69 @@ func NewClient(serverUrl, apiKey string) *Client { return nil }) - return &Client{ - client: client, - } + return &Client{client}, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { +func (c *Client) SetTimeout(timeout time.Duration) *Client { c.client.SetTimeout(timeout) return c } -func (c *Client) WithTLSConfig(config *tls.Config) *Client { +func (c *Client) SetTLSConfig(config *tls.Config) *Client { c.client.SetTLSClientConfig(config) return c } -func (c *Client) sendRequest(method string, path string, params interface{}) (*resty.Response, error) { - req := c.client.R() - if strings.EqualFold(method, http.MethodGet) { - qs := make(map[string]string) - if params != nil { - temp := make(map[string]any) - jsonb, _ := json.Marshal(params) - json.Unmarshal(jsonb, &temp) - for k, v := range temp { - if v != nil { - qs[k] = fmt.Sprintf("%v", v) - } - } - } - - req = req.SetQueryParams(qs) - } else { - req = req.SetHeader("Content-Type", "application/json").SetBody(params) +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") } - resp, err := req.Execute(method, path) + req := c.client.R() + req.Method = method + req.URL = path + return req, nil +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + // WARN: + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. + + resp, err := req.Send() if err != nil { - return resp, fmt.Errorf("apisix api error: failed to send request: %w", err) + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) } else if resp.IsError() { - return resp, fmt.Errorf("apisix api error: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) } return resp, nil } -func (c *Client) sendRequestWithResult(method string, path string, params interface{}, result interface{}) error { - resp, err := c.sendRequest(method, path, params) +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + resp, err := c.doRequest(req) if err != nil { if resp != nil { - json.Unmarshal(resp.Body(), &result) + json.Unmarshal(resp.Body(), &res) } - return err + return resp, err } - if err := json.Unmarshal(resp.Body(), &result); err != nil { - return fmt.Errorf("apisix api error: failed to unmarshal response: %w", err) + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) + } } - return nil + return resp, nil } diff --git a/internal/pkg/sdk3rd/apisix/models.go b/internal/pkg/sdk3rd/apisix/models.go deleted file mode 100644 index 960c8489..00000000 --- a/internal/pkg/sdk3rd/apisix/models.go +++ /dev/null @@ -1,12 +0,0 @@ -package apisix - -type UpdateSSLRequest struct { - ID string `json:"-"` - Cert *string `json:"cert,omitempty"` - Key *string `json:"key,omitempty"` - SNIs *[]string `json:"snis,omitempty"` - Type *string `json:"type,omitempty"` - Status *int32 `json:"status,omitempty"` -} - -type UpdateSSLResponse struct{} diff --git a/internal/pkg/sdk3rd/apisix/types.go b/internal/pkg/sdk3rd/apisix/types.go new file mode 100644 index 00000000..a2b30d4f --- /dev/null +++ b/internal/pkg/sdk3rd/apisix/types.go @@ -0,0 +1,7 @@ +package apisix + +type apiResponse interface{} + +type apiResponseBase struct{} + +var _ apiResponse = (*apiResponseBase)(nil) diff --git a/internal/pkg/sdk3rd/azure/common/config.go b/internal/pkg/sdk3rd/azure/env/config.go similarity index 66% rename from internal/pkg/sdk3rd/azure/common/config.go rename to internal/pkg/sdk3rd/azure/env/config.go index 45a1e490..5599df8a 100644 --- a/internal/pkg/sdk3rd/azure/common/config.go +++ b/internal/pkg/sdk3rd/azure/env/config.go @@ -1,4 +1,4 @@ -package common +package env import ( "fmt" @@ -7,7 +7,7 @@ import ( "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" ) -func IsEnvironmentPublic(env string) bool { +func IsPublicEnv(env string) bool { switch strings.ToLower(env) { case "", "default", "public", "azurecloud": return true @@ -16,7 +16,7 @@ func IsEnvironmentPublic(env string) bool { } } -func IsEnvironmentGovernment(env string) bool { +func IsUSGovernmentEnv(env string) bool { switch strings.ToLower(env) { case "usgovernment", "government", "azureusgovernment", "azuregovernment": return true @@ -25,7 +25,7 @@ func IsEnvironmentGovernment(env string) bool { } } -func IsEnvironmentChina(env string) bool { +func IsChinaEnv(env string) bool { switch strings.ToLower(env) { case "china", "chinacloud", "azurechina", "azurechinacloud": return true @@ -34,12 +34,12 @@ func IsEnvironmentChina(env string) bool { } } -func GetCloudEnvironmentConfiguration(env string) (cloud.Configuration, error) { - if IsEnvironmentPublic(env) { +func GetCloudEnvConfiguration(env string) (cloud.Configuration, error) { + if IsPublicEnv(env) { return cloud.AzurePublic, nil - } else if IsEnvironmentGovernment(env) { + } else if IsUSGovernmentEnv(env) { return cloud.AzureGovernment, nil - } else if IsEnvironmentChina(env) { + } else if IsChinaEnv(env) { return cloud.AzureChina, nil } diff --git a/internal/pkg/sdk3rd/baiducloud/cert/api.go b/internal/pkg/sdk3rd/baiducloud/cert/cert.go similarity index 100% rename from internal/pkg/sdk3rd/baiducloud/cert/api.go rename to internal/pkg/sdk3rd/baiducloud/cert/cert.go diff --git a/internal/pkg/sdk3rd/baiducloud/cert/client.go b/internal/pkg/sdk3rd/baiducloud/cert/client.go index 02c4feff..e2e6f150 100644 --- a/internal/pkg/sdk3rd/baiducloud/cert/client.go +++ b/internal/pkg/sdk3rd/baiducloud/cert/client.go @@ -13,5 +13,6 @@ func NewClient(ak, sk, endPoint string) (*Client, error) { if err != nil { return nil, err } + return &Client{client}, nil } diff --git a/internal/pkg/sdk3rd/baiducloud/cert/models.go b/internal/pkg/sdk3rd/baiducloud/cert/model.go similarity index 100% rename from internal/pkg/sdk3rd/baiducloud/cert/models.go rename to internal/pkg/sdk3rd/baiducloud/cert/model.go diff --git a/internal/pkg/sdk3rd/baishan/api.go b/internal/pkg/sdk3rd/baishan/api.go deleted file mode 100644 index dba90fad..00000000 --- a/internal/pkg/sdk3rd/baishan/api.go +++ /dev/null @@ -1,23 +0,0 @@ -package baishan - -import ( - "net/http" -) - -func (c *Client) CreateCertificate(req *CreateCertificateRequest) (*CreateCertificateResponse, error) { - resp := &CreateCertificateResponse{} - err := c.sendRequestWithResult(http.MethodPost, "/v2/domain/certificate", req, resp) - return resp, err -} - -func (c *Client) GetDomainConfig(req *GetDomainConfigRequest) (*GetDomainConfigResponse, error) { - resp := &GetDomainConfigResponse{} - err := c.sendRequestWithResult(http.MethodGet, "/v2/domain/config", req, resp) - return resp, err -} - -func (c *Client) SetDomainConfig(req *SetDomainConfigRequest) (*SetDomainConfigResponse, error) { - resp := &SetDomainConfigResponse{} - err := c.sendRequestWithResult(http.MethodPost, "/v2/domain/config", req, resp) - return resp, err -} diff --git a/internal/pkg/sdk3rd/baishan/api_get_domain_config.go b/internal/pkg/sdk3rd/baishan/api_get_domain_config.go new file mode 100644 index 00000000..bbaae26d --- /dev/null +++ b/internal/pkg/sdk3rd/baishan/api_get_domain_config.go @@ -0,0 +1,49 @@ +package baishan + +import ( + "context" + "net/http" +) + +type GetDomainConfigRequest struct { + Domains *string `json:"domains,omitempty"` + Config *[]string `json:"config,omitempty"` +} + +type GetDomainConfigResponse struct { + apiResponseBase + + Data []*struct { + Domain string `json:"domain"` + Config *DomainConfig `json:"config"` + } `json:"data,omitempty"` +} + +func (c *Client) GetDomainConfig(req *GetDomainConfigRequest) (*GetDomainConfigResponse, error) { + return c.GetDomainConfigWithContext(context.Background(), req) +} + +func (c *Client) GetDomainConfigWithContext(ctx context.Context, req *GetDomainConfigRequest) (*GetDomainConfigResponse, error) { + httpreq, err := c.newRequest(http.MethodGet, "/v2/domain/config") + if err != nil { + return nil, err + } else { + if req.Domains != nil { + httpreq.SetQueryParam("domains", *req.Domains) + } + if req.Config != nil { + for _, config := range *req.Config { + httpreq.QueryParam.Add("config[]", config) + } + } + + httpreq.SetContext(ctx) + } + + result := &GetDomainConfigResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/baishan/api_set_domain_certificate.go b/internal/pkg/sdk3rd/baishan/api_set_domain_certificate.go new file mode 100644 index 00000000..3dd3b0b6 --- /dev/null +++ b/internal/pkg/sdk3rd/baishan/api_set_domain_certificate.go @@ -0,0 +1,40 @@ +package baishan + +import ( + "context" + "net/http" +) + +type SetDomainCertificateRequest struct { + CertificateId *string `json:"cert_id,omitempty"` + Certificate *string `json:"certificate,omitempty"` + Key *string `json:"key,omitempty"` + Name *string `json:"name,omitempty"` +} + +type SetDomainCertificateResponse struct { + apiResponseBase + + Data *DomainCertificate `json:"data,omitempty"` +} + +func (c *Client) SetDomainCertificate(req *SetDomainCertificateRequest) (*SetDomainCertificateResponse, error) { + return c.SetDomainCertificateWithContext(context.Background(), req) +} + +func (c *Client) SetDomainCertificateWithContext(ctx context.Context, req *SetDomainCertificateRequest) (*SetDomainCertificateResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/v2/domain/certificate") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &SetDomainCertificateResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/baishan/api_set_domain_config.go b/internal/pkg/sdk3rd/baishan/api_set_domain_config.go new file mode 100644 index 00000000..fcc876c4 --- /dev/null +++ b/internal/pkg/sdk3rd/baishan/api_set_domain_config.go @@ -0,0 +1,40 @@ +package baishan + +import ( + "context" + "net/http" +) + +type SetDomainConfigRequest struct { + Domains *string `json:"domains,omitempty"` + Config *DomainConfig `json:"config,omitempty"` +} + +type SetDomainConfigResponse struct { + apiResponseBase + + Data *struct { + Config *DomainConfig `json:"config"` + } `json:"data,omitempty"` +} + +func (c *Client) SetDomainConfig(req *SetDomainConfigRequest) (*SetDomainConfigResponse, error) { + return c.SetDomainConfigWithContext(context.Background(), req) +} + +func (c *Client) SetDomainConfigWithContext(ctx context.Context, req *SetDomainConfigRequest) (*SetDomainConfigResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/v2/domain/config") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &SetDomainConfigResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/baishan/client.go b/internal/pkg/sdk3rd/baishan/client.go index 7922096e..fb9a1df7 100644 --- a/internal/pkg/sdk3rd/baishan/client.go +++ b/internal/pkg/sdk3rd/baishan/client.go @@ -3,10 +3,6 @@ package baishan import ( "encoding/json" "fmt" - "net/http" - "net/url" - "reflect" - "strings" "time" "github.com/go-resty/resty/v2" @@ -16,78 +12,80 @@ type Client struct { client *resty.Client } -func NewClient(apiToken string) *Client { +func NewClient(apiToken string) (*Client, error) { + if apiToken == "" { + return nil, fmt.Errorf("sdkerr: unset apiToken") + } + client := resty.New(). SetBaseURL("https://cdn.api.baishan.com"). + SetHeader("Accept", "application/json"). + SetHeader("Content-Type", "application/json"). SetHeader("User-Agent", "certimate"). SetHeader("Token", apiToken) - return &Client{ - client: client, - } + return &Client{client}, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { +func (c *Client) SetTimeout(timeout time.Duration) *Client { c.client.SetTimeout(timeout) return c } -func (c *Client) sendRequest(method string, path string, params interface{}) (*resty.Response, error) { - req := c.client.R() - if strings.EqualFold(method, http.MethodGet) { - qs := url.Values{} - if params != nil { - temp := make(map[string]any) - jsonb, _ := json.Marshal(params) - json.Unmarshal(jsonb, &temp) - for k, v := range temp { - if v != nil { - rv := reflect.ValueOf(v) - switch rv.Kind() { - case reflect.Slice, reflect.Array: - for i := 0; i < rv.Len(); i++ { - qs.Add(fmt.Sprintf("%s[]", k), fmt.Sprintf("%v", rv.Index(i).Interface())) - } - case reflect.Map: - for _, rk := range rv.MapKeys() { - qs.Add(fmt.Sprintf("%s[%s]", k, rk.Interface()), fmt.Sprintf("%v", rv.MapIndex(rk).Interface())) - } - default: - qs.Set(k, fmt.Sprintf("%v", v)) - } - } - } - } - - req = req.SetQueryParamsFromValues(qs) - } else { - req = req.SetHeader("Content-Type", "application/json").SetBody(params) +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") } - resp, err := req.Execute(method, path) + req := c.client.R() + req.Method = method + req.URL = path + return req, nil +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + // WARN: + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. + + resp, err := req.Send() if err != nil { - return resp, fmt.Errorf("baishan api error: failed to send request: %w", err) + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) } else if resp.IsError() { - return resp, fmt.Errorf("baishan api error: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) } return resp, nil } -func (c *Client) sendRequestWithResult(method string, path string, params interface{}, result BaseResponse) error { - resp, err := c.sendRequest(method, path, params) +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + resp, err := c.doRequest(req) if err != nil { if resp != nil { - json.Unmarshal(resp.Body(), &result) + json.Unmarshal(resp.Body(), &res) } - return err + return resp, err } - if err := json.Unmarshal(resp.Body(), &result); err != nil { - return fmt.Errorf("baishan api error: failed to unmarshal response: %w", err) - } else if errcode := result.GetCode(); errcode != 0 { - return fmt.Errorf("baishan api error: code='%d', message='%s'", errcode, result.GetMessage()) + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) + } else { + if tcode := res.GetCode(); tcode != 0 { + return resp, fmt.Errorf("sdkerr: code='%d', message='%s'", tcode, res.GetMessage()) + } + } } - return nil + return resp, nil } diff --git a/internal/pkg/sdk3rd/baishan/models.go b/internal/pkg/sdk3rd/baishan/models.go deleted file mode 100644 index 457729e8..00000000 --- a/internal/pkg/sdk3rd/baishan/models.go +++ /dev/null @@ -1,82 +0,0 @@ -package baishan - -import "encoding/json" - -type BaseResponse interface { - GetCode() int32 - GetMessage() string -} - -type baseResponse struct { - Code *int32 `json:"code,omitempty"` - Message *string `json:"message,omitempty"` -} - -func (r *baseResponse) GetCode() int32 { - if r.Code != nil { - return *r.Code - } - return 0 -} - -func (r *baseResponse) GetMessage() string { - if r.Message != nil { - return *r.Message - } - return "" -} - -type CreateCertificateRequest struct { - CertificateId *string `json:"cert_id,omitempty"` - Certificate string `json:"certificate"` - Key string `json:"key"` - Name string `json:"name"` -} - -type CreateCertificateResponse struct { - baseResponse - Data *DomainCertificate `json:"data,omitempty"` -} - -type GetDomainConfigRequest struct { - Domains string `json:"domains"` - Config []string `json:"config"` -} - -type GetDomainConfigResponse struct { - baseResponse - Data []*struct { - Domain string `json:"domain"` - Config *DomainConfig `json:"config"` - } `json:"data,omitempty"` -} - -type SetDomainConfigRequest struct { - Domains string `json:"domains"` - Config *DomainConfig `json:"config"` -} - -type SetDomainConfigResponse struct { - baseResponse - Data *struct { - Config *DomainConfig `json:"config"` - } `json:"data,omitempty"` -} - -type DomainCertificate struct { - CertId json.Number `json:"cert_id"` - Name string `json:"name"` - CertStartTime string `json:"cert_start_time"` - CertExpireTime string `json:"cert_expire_time"` -} - -type DomainConfig struct { - Https *DomainConfigHttps `json:"https"` -} - -type DomainConfigHttps struct { - CertId json.Number `json:"cert_id"` - ForceHttps *string `json:"force_https,omitempty"` - EnableHttp2 *string `json:"http2,omitempty"` - EnableOcsp *string `json:"ocsp,omitempty"` -} diff --git a/internal/pkg/sdk3rd/baishan/types.go b/internal/pkg/sdk3rd/baishan/types.go new file mode 100644 index 00000000..b6bda59f --- /dev/null +++ b/internal/pkg/sdk3rd/baishan/types.go @@ -0,0 +1,49 @@ +package baishan + +import "encoding/json" + +type apiResponse interface { + GetCode() int32 + GetMessage() string +} + +type apiResponseBase struct { + Code *int32 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` +} + +func (r *apiResponseBase) GetCode() int32 { + if r.Code == nil { + return 0 + } + + return *r.Code +} + +func (r *apiResponseBase) GetMessage() string { + if r.Message == nil { + return "" + } + + return *r.Message +} + +var _ apiResponse = (*apiResponseBase)(nil) + +type DomainCertificate struct { + CertId json.Number `json:"cert_id"` + Name string `json:"name"` + CertStartTime string `json:"cert_start_time"` + CertExpireTime string `json:"cert_expire_time"` +} + +type DomainConfig struct { + Https *DomainConfigHttps `json:"https"` +} + +type DomainConfigHttps struct { + CertId json.Number `json:"cert_id"` + ForceHttps *string `json:"force_https,omitempty"` + EnableHttp2 *string `json:"http2,omitempty"` + EnableOcsp *string `json:"ocsp,omitempty"` +} diff --git a/internal/pkg/sdk3rd/btpanel/api.go b/internal/pkg/sdk3rd/btpanel/api.go deleted file mode 100644 index 926e03e5..00000000 --- a/internal/pkg/sdk3rd/btpanel/api.go +++ /dev/null @@ -1,31 +0,0 @@ -package btpanel - -func (c *Client) ConfigSavePanelSSL(req *ConfigSavePanelSSLRequest) (*ConfigSavePanelSSLResponse, error) { - resp := &ConfigSavePanelSSLResponse{} - err := c.sendRequestWithResult("/config?action=SavePanelSSL", req, resp) - return resp, err -} - -func (c *Client) SiteSetSSL(req *SiteSetSSLRequest) (*SiteSetSSLResponse, error) { - resp := &SiteSetSSLResponse{} - err := c.sendRequestWithResult("/site?action=SetSSL", req, resp) - return resp, err -} - -func (c *Client) SystemServiceAdmin(req *SystemServiceAdminRequest) (*SystemServiceAdminResponse, error) { - resp := &SystemServiceAdminResponse{} - err := c.sendRequestWithResult("/system?action=ServiceAdmin", req, resp) - return resp, err -} - -func (c *Client) SSLCertSaveCert(req *SSLCertSaveCertRequest) (*SSLCertSaveCertResponse, error) { - resp := &SSLCertSaveCertResponse{} - err := c.sendRequestWithResult("/ssl/cert/save_cert", req, resp) - return resp, err -} - -func (c *Client) SSLSetBatchCertToSite(req *SSLSetBatchCertToSiteRequest) (*SSLSetBatchCertToSiteResponse, error) { - resp := &SSLSetBatchCertToSiteResponse{} - err := c.sendRequestWithResult("/ssl?action=SetBatchCertToSite", req, resp) - return resp, err -} diff --git a/internal/pkg/sdk3rd/btpanel/api_config_save_panel_ssl.go b/internal/pkg/sdk3rd/btpanel/api_config_save_panel_ssl.go new file mode 100644 index 00000000..76b343b1 --- /dev/null +++ b/internal/pkg/sdk3rd/btpanel/api_config_save_panel_ssl.go @@ -0,0 +1,35 @@ +package btpanel + +import ( + "context" + "net/http" +) + +type ConfigSavePanelSSLRequest struct { + PrivateKey string `json:"privateKey"` + Certificate string `json:"certPem"` +} + +type ConfigSavePanelSSLResponse struct { + apiResponseBase +} + +func (c *Client) ConfigSavePanelSSL(req *ConfigSavePanelSSLRequest) (*ConfigSavePanelSSLResponse, error) { + return c.ConfigSavePanelSSLWithContext(context.Background(), req) +} + +func (c *Client) ConfigSavePanelSSLWithContext(ctx context.Context, req *ConfigSavePanelSSLRequest) (*ConfigSavePanelSSLResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/config?action=SavePanelSSL", req) + if err != nil { + return nil, err + } else { + httpreq.SetContext(ctx) + } + + result := &ConfigSavePanelSSLResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/btpanel/api_site_set_ssl.go b/internal/pkg/sdk3rd/btpanel/api_site_set_ssl.go new file mode 100644 index 00000000..95b422ae --- /dev/null +++ b/internal/pkg/sdk3rd/btpanel/api_site_set_ssl.go @@ -0,0 +1,37 @@ +package btpanel + +import ( + "context" + "net/http" +) + +type SiteSetSSLRequest struct { + Type string `json:"type"` + SiteName string `json:"siteName"` + PrivateKey string `json:"key"` + Certificate string `json:"csr"` +} + +type SiteSetSSLResponse struct { + apiResponseBase +} + +func (c *Client) SiteSetSSL(req *SiteSetSSLRequest) (*SiteSetSSLResponse, error) { + return c.SiteSetSSLWithContext(context.Background(), req) +} + +func (c *Client) SiteSetSSLWithContext(ctx context.Context, req *SiteSetSSLRequest) (*SiteSetSSLResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/site?action=SetSSL", req) + if err != nil { + return nil, err + } else { + httpreq.SetContext(ctx) + } + + result := &SiteSetSSLResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/btpanel/api_ssl_cert_save_cert.go b/internal/pkg/sdk3rd/btpanel/api_ssl_cert_save_cert.go new file mode 100644 index 00000000..96f5b554 --- /dev/null +++ b/internal/pkg/sdk3rd/btpanel/api_ssl_cert_save_cert.go @@ -0,0 +1,37 @@ +package btpanel + +import ( + "context" + "net/http" +) + +type SSLCertSaveCertRequest struct { + PrivateKey string `json:"key"` + Certificate string `json:"csr"` +} + +type SSLCertSaveCertResponse struct { + apiResponseBase + + SSLHash string `json:"ssl_hash"` +} + +func (c *Client) SSLCertSaveCert(req *SSLCertSaveCertRequest) (*SSLCertSaveCertResponse, error) { + return c.SSLCertSaveCertWithContext(context.Background(), req) +} + +func (c *Client) SSLCertSaveCertWithContext(ctx context.Context, req *SSLCertSaveCertRequest) (*SSLCertSaveCertResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/ssl/cert/save_cert", req) + if err != nil { + return nil, err + } else { + httpreq.SetContext(ctx) + } + + result := &SSLCertSaveCertResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/btpanel/api_ssl_set_batch_cert_to_site.go b/internal/pkg/sdk3rd/btpanel/api_ssl_set_batch_cert_to_site.go new file mode 100644 index 00000000..3d5b0cfd --- /dev/null +++ b/internal/pkg/sdk3rd/btpanel/api_ssl_set_batch_cert_to_site.go @@ -0,0 +1,44 @@ +package btpanel + +import ( + "context" + "net/http" +) + +type SSLSetBatchCertToSiteRequest struct { + BatchInfo []*SSLSetBatchCertToSiteRequestBatchInfo `json:"BatchInfo"` +} + +type SSLSetBatchCertToSiteRequestBatchInfo struct { + SSLHash string `json:"ssl_hash"` + SiteName string `json:"siteName"` + CertName string `json:"certName"` +} + +type SSLSetBatchCertToSiteResponse struct { + apiResponseBase + + TotalCount int32 `json:"total"` + SuccessCount int32 `json:"success"` + FailedCount int32 `json:"faild"` +} + +func (c *Client) SSLSetBatchCertToSite(req *SSLSetBatchCertToSiteRequest) (*SSLSetBatchCertToSiteResponse, error) { + return c.SSLSetBatchCertToSiteWithContext(context.Background(), req) +} + +func (c *Client) SSLSetBatchCertToSiteWithContext(ctx context.Context, req *SSLSetBatchCertToSiteRequest) (*SSLSetBatchCertToSiteResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/ssl?action=SetBatchCertToSite", req) + if err != nil { + return nil, err + } else { + httpreq.SetContext(ctx) + } + + result := &SSLSetBatchCertToSiteResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/btpanel/api_system_service_admin.go b/internal/pkg/sdk3rd/btpanel/api_system_service_admin.go new file mode 100644 index 00000000..f9c19cea --- /dev/null +++ b/internal/pkg/sdk3rd/btpanel/api_system_service_admin.go @@ -0,0 +1,35 @@ +package btpanel + +import ( + "context" + "net/http" +) + +type SystemServiceAdminRequest struct { + Name string `json:"name"` + Type string `json:"type"` +} + +type SystemServiceAdminResponse struct { + apiResponseBase +} + +func (c *Client) SystemServiceAdmin(req *SystemServiceAdminRequest) (*SystemServiceAdminResponse, error) { + return c.SystemServiceAdminWithContext(context.Background(), req) +} + +func (c *Client) SystemServiceAdminWithContext(ctx context.Context, req *SystemServiceAdminRequest) (*SystemServiceAdminResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/system?action=ServiceAdmin", req) + if err != nil { + return nil, err + } else { + httpreq.SetContext(ctx) + } + + result := &SystemServiceAdminResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/btpanel/client.go b/internal/pkg/sdk3rd/btpanel/client.go index 7faa46c0..8b8cff64 100644 --- a/internal/pkg/sdk3rd/btpanel/client.go +++ b/internal/pkg/sdk3rd/btpanel/client.go @@ -6,6 +6,7 @@ import ( "encoding/hex" "encoding/json" "fmt" + "net/url" "reflect" "strings" "time" @@ -19,39 +20,46 @@ type Client struct { client *resty.Client } -func NewClient(serverUrl, apiKey string) *Client { +func NewClient(serverUrl, apiKey string) (*Client, error) { + if serverUrl == "" { + return nil, fmt.Errorf("sdkerr: unset serverUrl") + } + if _, err := url.Parse(serverUrl); err != nil { + return nil, fmt.Errorf("sdkerr: invalid serverUrl: %w", err) + } + if apiKey == "" { + return nil, fmt.Errorf("sdkerr: unset apiKey") + } + client := resty.New(). SetBaseURL(strings.TrimRight(serverUrl, "/")). + SetHeader("Accept", "application/json"). SetHeader("Content-Type", "application/x-www-form-urlencoded"). SetHeader("User-Agent", "certimate") return &Client{ apiKey: apiKey, client: client, - } + }, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { +func (c *Client) SetTimeout(timeout time.Duration) *Client { c.client.SetTimeout(timeout) return c } -func (c *Client) WithTLSConfig(config *tls.Config) *Client { +func (c *Client) SetTLSConfig(config *tls.Config) *Client { c.client.SetTLSClientConfig(config) return c } -func (c *Client) generateSignature(timestamp string) string { - keyMd5 := md5.Sum([]byte(c.apiKey)) - keyMd5Hex := strings.ToLower(hex.EncodeToString(keyMd5[:])) - - signMd5 := md5.Sum([]byte(timestamp + keyMd5Hex)) - signMd5Hex := strings.ToLower(hex.EncodeToString(signMd5[:])) - return signMd5Hex -} - -func (c *Client) sendRequest(path string, params interface{}) (*resty.Response, error) { - timestamp := time.Now().Unix() +func (c *Client) newRequest(method string, path string, params any) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") + } data := make(map[string]string) if params != nil { @@ -59,52 +67,93 @@ func (c *Client) sendRequest(path string, params interface{}) (*resty.Response, jsonb, _ := json.Marshal(params) json.Unmarshal(jsonb, &temp) for k, v := range temp { - if v != nil { - switch reflect.Indirect(reflect.ValueOf(v)).Kind() { - case reflect.String: - data[k] = v.(string) - case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64: - data[k] = fmt.Sprintf("%v", v) - default: - if t, ok := v.(time.Time); ok { - data[k] = t.Format(time.RFC3339) - } else { - jbytes, _ := json.Marshal(v) - data[k] = string(jbytes) - } + if v == nil { + continue + } + + switch reflect.Indirect(reflect.ValueOf(v)).Kind() { + case reflect.String: + data[k] = v.(string) + + case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64: + data[k] = fmt.Sprintf("%v", v) + + default: + if t, ok := v.(time.Time); ok { + data[k] = t.Format(time.RFC3339) + } else { + jsonb, _ := json.Marshal(v) + data[k] = string(jsonb) } } } } - data["request_time"] = fmt.Sprintf("%d", timestamp) - data["request_token"] = c.generateSignature(fmt.Sprintf("%d", timestamp)) - req := c.client.R().SetFormData(data) - resp, err := req.Post(path) + timestamp := time.Now().Unix() + data["request_time"] = fmt.Sprintf("%d", timestamp) + data["request_token"] = generateSignature(fmt.Sprintf("%d", timestamp), c.apiKey) + + req := c.client.R() + req.Method = method + req.URL = path + req.SetFormData(data) + return req, nil +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + // WARN: + // PLEASE DO NOT USE `req.SetBody` or `req.SetFormData` HERE! USE `newRequest` INSTEAD. + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. + + resp, err := req.Send() if err != nil { - return resp, fmt.Errorf("baota api error: failed to send request: %w", err) + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) } else if resp.IsError() { - return resp, fmt.Errorf("baota api error: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) } return resp, nil } -func (c *Client) sendRequestWithResult(path string, params interface{}, result BaseResponse) error { - resp, err := c.sendRequest(path, params) - if err != nil { - return err +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") } - if err := json.Unmarshal(resp.Body(), &result); err != nil { - return fmt.Errorf("baota api error: failed to unmarshal response: %w", err) - } else if errstatus := result.GetStatus(); errstatus != nil && !*errstatus { - if result.GetMessage() == nil { - return fmt.Errorf("baota api error: unknown error") + resp, err := c.doRequest(req) + if err != nil { + if resp != nil { + json.Unmarshal(resp.Body(), &res) + } + return resp, err + } + + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) } else { - return fmt.Errorf("baota api error: message='%s'", *result.GetMessage()) + if tstatus := res.GetStatus(); tstatus != nil && !*tstatus { + if res.GetMessage() == nil { + return resp, fmt.Errorf("sdkerr: api error: unknown error") + } else { + return resp, fmt.Errorf("sdkerr: api error: message='%s'", *res.GetMessage()) + } + } } } - return nil + return resp, nil +} + +func generateSignature(timestamp string, apiKey string) string { + keyMd5 := md5.Sum([]byte(apiKey)) + keyMd5Hex := strings.ToLower(hex.EncodeToString(keyMd5[:])) + + signMd5 := md5.Sum([]byte(timestamp + keyMd5Hex)) + signMd5Hex := strings.ToLower(hex.EncodeToString(signMd5[:])) + return signMd5Hex } diff --git a/internal/pkg/sdk3rd/btpanel/models.go b/internal/pkg/sdk3rd/btpanel/models.go deleted file mode 100644 index 923efeda..00000000 --- a/internal/pkg/sdk3rd/btpanel/models.go +++ /dev/null @@ -1,75 +0,0 @@ -package btpanel - -type BaseResponse interface { - GetStatus() *bool - GetMessage() *string -} - -type baseResponse struct { - Status *bool `json:"status,omitempty"` - Message *string `json:"msg,omitempty"` -} - -func (r *baseResponse) GetStatus() *bool { - return r.Status -} - -func (r *baseResponse) GetMessage() *string { - return r.Message -} - -type ConfigSavePanelSSLRequest struct { - PrivateKey string `json:"privateKey"` - Certificate string `json:"certPem"` -} - -type ConfigSavePanelSSLResponse struct { - baseResponse -} - -type SiteSetSSLRequest struct { - Type string `json:"type"` - SiteName string `json:"siteName"` - PrivateKey string `json:"key"` - Certificate string `json:"csr"` -} - -type SiteSetSSLResponse struct { - baseResponse -} - -type SystemServiceAdminRequest struct { - Name string `json:"name"` - Type string `json:"type"` -} - -type SystemServiceAdminResponse struct { - baseResponse -} - -type SSLCertSaveCertRequest struct { - PrivateKey string `json:"key"` - Certificate string `json:"csr"` -} - -type SSLCertSaveCertResponse struct { - baseResponse - SSLHash string `json:"ssl_hash"` -} - -type SSLSetBatchCertToSiteRequest struct { - BatchInfo []*SSLSetBatchCertToSiteRequestBatchInfo `json:"BatchInfo"` -} - -type SSLSetBatchCertToSiteRequestBatchInfo struct { - SSLHash string `json:"ssl_hash"` - SiteName string `json:"siteName"` - CertName string `json:"certName"` -} - -type SSLSetBatchCertToSiteResponse struct { - baseResponse - TotalCount int32 `json:"total"` - SuccessCount int32 `json:"success"` - FailedCount int32 `json:"faild"` -} diff --git a/internal/pkg/sdk3rd/btpanel/types.go b/internal/pkg/sdk3rd/btpanel/types.go new file mode 100644 index 00000000..ecaf51d2 --- /dev/null +++ b/internal/pkg/sdk3rd/btpanel/types.go @@ -0,0 +1,19 @@ +package btpanel + +type apiResponse interface { + GetStatus() *bool + GetMessage() *string +} + +type apiResponseBase struct { + Status *bool `json:"status,omitempty"` + Message *string `json:"msg,omitempty"` +} + +func (r *apiResponseBase) GetStatus() *bool { + return r.Status +} + +func (r *apiResponseBase) GetMessage() *string { + return r.Message +} diff --git a/internal/pkg/sdk3rd/btwaf/api.go b/internal/pkg/sdk3rd/btwaf/api.go deleted file mode 100644 index bc35dee5..00000000 --- a/internal/pkg/sdk3rd/btwaf/api.go +++ /dev/null @@ -1,19 +0,0 @@ -package btwaf - -func (c *Client) GetSiteList(req *GetSiteListRequest) (*GetSiteListResponse, error) { - resp := &GetSiteListResponse{} - err := c.sendRequestWithResult("/wafmastersite/get_site_list", req, resp) - return resp, err -} - -func (c *Client) ModifySite(req *ModifySiteRequest) (*ModifySiteResponse, error) { - resp := &ModifySiteResponse{} - err := c.sendRequestWithResult("/wafmastersite/modify_site", req, resp) - return resp, err -} - -func (c *Client) ConfigSetSSL(req *ConfigSetSSLRequest) (*ConfigSetSSLResponse, error) { - resp := &ConfigSetSSLResponse{} - err := c.sendRequestWithResult("/config/set_cert", req, resp) - return resp, err -} diff --git a/internal/pkg/sdk3rd/btwaf/api_config_set_cert.go b/internal/pkg/sdk3rd/btwaf/api_config_set_cert.go new file mode 100644 index 00000000..1f93ec59 --- /dev/null +++ b/internal/pkg/sdk3rd/btwaf/api_config_set_cert.go @@ -0,0 +1,36 @@ +package btwaf + +import ( + "context" + "net/http" +) + +type ConfigSetCertRequest struct { + CertContent *string `json:"certContent,omitempty"` + KeyContent *string `json:"keyContent,omitempty"` +} + +type ConfigSetCertResponse struct { + apiResponseBase +} + +func (c *Client) ConfigSetCert(req *ConfigSetCertRequest) (*ConfigSetCertResponse, error) { + return c.ConfigSetCertWithContext(context.Background(), req) +} + +func (c *Client) ConfigSetCertWithContext(ctx context.Context, req *ConfigSetCertRequest) (*ConfigSetCertResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/config/set_cert") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &ConfigSetCertResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/btwaf/api_get_site_list.go b/internal/pkg/sdk3rd/btwaf/api_get_site_list.go new file mode 100644 index 00000000..7cb6c05d --- /dev/null +++ b/internal/pkg/sdk3rd/btwaf/api_get_site_list.go @@ -0,0 +1,42 @@ +package btwaf + +import ( + "context" + "net/http" +) + +type GetSiteListRequest struct { + Page *int32 `json:"p,omitempty"` + PageSize *int32 `json:"p_size,omitempty"` + SiteName *string `json:"site_name,omitempty"` +} + +type GetSiteListResponse struct { + apiResponseBase + + Result *struct { + List []*SiteRecord `json:"list"` + Total int32 `json:"total"` + } `json:"res,omitempty"` +} + +func (c *Client) GetSiteList(req *GetSiteListRequest) (*GetSiteListResponse, error) { + return c.GetSiteListWithContext(context.Background(), req) +} + +func (c *Client) GetSiteListWithContext(ctx context.Context, req *GetSiteListRequest) (*GetSiteListResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/wafmastersite/get_site_list") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &GetSiteListResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/btwaf/api_modify_site.go b/internal/pkg/sdk3rd/btwaf/api_modify_site.go new file mode 100644 index 00000000..516277ec --- /dev/null +++ b/internal/pkg/sdk3rd/btwaf/api_modify_site.go @@ -0,0 +1,37 @@ +package btwaf + +import ( + "context" + "net/http" +) + +type ModifySiteRequest struct { + SiteId *string `json:"site_id,omitempty"` + Type *string `json:"types,omitempty"` + Server *SiteServerInfo `json:"server,omitempty"` +} + +type ModifySiteResponse struct { + apiResponseBase +} + +func (c *Client) ModifySite(req *ModifySiteRequest) (*ModifySiteResponse, error) { + return c.ModifySiteWithContext(context.Background(), req) +} + +func (c *Client) ModifySiteWithContext(ctx context.Context, req *ModifySiteRequest) (*ModifySiteResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/wafmastersite/modify_site") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &ModifySiteResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/btwaf/client.go b/internal/pkg/sdk3rd/btwaf/client.go index 4bf76b16..a3be8ae9 100644 --- a/internal/pkg/sdk3rd/btwaf/client.go +++ b/internal/pkg/sdk3rd/btwaf/client.go @@ -7,6 +7,7 @@ import ( "encoding/json" "fmt" "net/http" + "net/url" "strings" "time" @@ -17,9 +18,20 @@ type Client struct { client *resty.Client } -func NewClient(serverUrl, apiKey string) *Client { +func NewClient(serverUrl, apiKey string) (*Client, error) { + if serverUrl == "" { + return nil, fmt.Errorf("sdkerr: unset serverUrl") + } + if _, err := url.Parse(serverUrl); err != nil { + return nil, fmt.Errorf("sdkerr: invalid serverUrl: %w", err) + } + if apiKey == "" { + return nil, fmt.Errorf("sdkerr: unset apiKey") + } + client := resty.New(). SetBaseURL(strings.TrimRight(serverUrl, "/")+"/api"). + SetHeader("Accept", "application/json"). SetHeader("Content-Type", "application/json"). SetHeader("User-Agent", "certimate"). SetPreRequestHook(func(c *resty.Client, req *http.Request) error { @@ -34,44 +46,73 @@ func NewClient(serverUrl, apiKey string) *Client { return nil }) - return &Client{ - client: client, - } + return &Client{client}, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { +func (c *Client) SetTimeout(timeout time.Duration) *Client { c.client.SetTimeout(timeout) return c } -func (c *Client) WithTLSConfig(config *tls.Config) *Client { +func (c *Client) SetTLSConfig(config *tls.Config) *Client { c.client.SetTLSClientConfig(config) return c } -func (c *Client) sendRequest(path string, params interface{}) (*resty.Response, error) { - req := c.client.R().SetBody(params) - resp, err := req.Post(path) +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") + } + + req := c.client.R() + req.Method = method + req.URL = path + return req, nil +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + // WARN: + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. + + resp, err := req.Send() if err != nil { - return resp, fmt.Errorf("baota api error: failed to send request: %w", err) + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) } else if resp.IsError() { - return resp, fmt.Errorf("baota api error: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) } return resp, nil } -func (c *Client) sendRequestWithResult(path string, params interface{}, result BaseResponse) error { - resp, err := c.sendRequest(path, params) +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + resp, err := c.doRequest(req) if err != nil { - return err + if resp != nil { + json.Unmarshal(resp.Body(), &res) + } + return resp, err } - if err := json.Unmarshal(resp.Body(), &result); err != nil { - return fmt.Errorf("baota api error: failed to unmarshal response: %w", err) - } else if errcode := result.GetCode(); errcode != 0 { - return fmt.Errorf("baota api error: code='%d'", errcode) + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) + } else { + if code := res.GetCode(); code != 0 { + return resp, fmt.Errorf("sdkerr: api error: code='%d'", code) + } + } } - return nil + return resp, nil } diff --git a/internal/pkg/sdk3rd/btwaf/models.go b/internal/pkg/sdk3rd/btwaf/models.go deleted file mode 100644 index 6217e1a5..00000000 --- a/internal/pkg/sdk3rd/btwaf/models.go +++ /dev/null @@ -1,67 +0,0 @@ -package btwaf - -type BaseResponse interface { - GetCode() int32 -} - -type baseResponse struct { - Code *int32 `json:"code,omitempty"` -} - -func (r *baseResponse) GetCode() int32 { - if r.Code != nil { - return *r.Code - } - return 0 -} - -type GetSiteListRequest struct { - Page *int32 `json:"p,omitempty"` - PageSize *int32 `json:"p_size,omitempty"` - SiteName *string `json:"site_name,omitempty"` -} - -type GetSiteListResponse struct { - baseResponse - Result *struct { - List []*struct { - SiteId string `json:"site_id"` - SiteName string `json:"site_name"` - Type string `json:"types"` - Status int32 `json:"status"` - CreateTime int64 `json:"create_time"` - UpdateTime int64 `json:"update_time"` - } `json:"list"` - Total int32 `json:"total"` - } `json:"res,omitempty"` -} - -type SiteServerInfo struct { - ListenSSLPorts *[]int32 `json:"listen_ssl_port,omitempty"` - SSL *SiteServerSSLInfo `json:"ssl,omitempty"` -} - -type SiteServerSSLInfo struct { - IsSSL *int32 `json:"is_ssl,omitempty"` - FullChain *string `json:"full_chain,omitempty"` - PrivateKey *string `json:"private_key,omitempty"` -} - -type ModifySiteRequest struct { - SiteId string `json:"site_id"` - Type *string `json:"types,omitempty"` - Server *SiteServerInfo `json:"server,omitempty"` -} - -type ModifySiteResponse struct { - baseResponse -} - -type ConfigSetSSLRequest struct { - CertContent string `json:"certContent"` - KeyContent string `json:"keyContent"` -} - -type ConfigSetSSLResponse struct { - baseResponse -} diff --git a/internal/pkg/sdk3rd/btwaf/types.go b/internal/pkg/sdk3rd/btwaf/types.go new file mode 100644 index 00000000..8c75a44b --- /dev/null +++ b/internal/pkg/sdk3rd/btwaf/types.go @@ -0,0 +1,39 @@ +package btwaf + +type apiResponse interface { + GetCode() int32 +} + +type apiResponseBase struct { + Code *int32 `json:"code,omitempty"` +} + +func (r *apiResponseBase) GetCode() int32 { + if r.Code == nil { + return 0 + } + + return *r.Code +} + +var _ apiResponse = (*apiResponseBase)(nil) + +type SiteRecord struct { + SiteId string `json:"site_id"` + SiteName string `json:"site_name"` + Type string `json:"types"` + Status int32 `json:"status"` + CreateTime int64 `json:"create_time"` + UpdateTime int64 `json:"update_time"` +} + +type SiteServerInfo struct { + ListenSSLPorts *[]int32 `json:"listen_ssl_port,omitempty"` + SSL *SiteServerSSLInfo `json:"ssl,omitempty"` +} + +type SiteServerSSLInfo struct { + IsSSL *int32 `json:"is_ssl,omitempty"` + FullChain *string `json:"full_chain,omitempty"` + PrivateKey *string `json:"private_key,omitempty"` +} diff --git a/internal/pkg/sdk3rd/bunny/api.go b/internal/pkg/sdk3rd/bunny/api.go deleted file mode 100644 index 01f27606..00000000 --- a/internal/pkg/sdk3rd/bunny/api.go +++ /dev/null @@ -1,16 +0,0 @@ -package bunny - -import ( - "fmt" - "net/http" - "net/url" -) - -func (c *Client) AddCustomCertificate(req *AddCustomCertificateRequest) ([]byte, error) { - if req.PullZoneId == "" { - return nil, fmt.Errorf("bunny api error: invalid parameter: PullZoneId") - } - - resp, err := c.sendRequest(http.MethodPost, fmt.Sprintf("/pullzone/%s/addCertificate", url.PathEscape(req.PullZoneId)), req) - return resp.Body(), err -} diff --git a/internal/pkg/sdk3rd/bunny/api_add_custom_certificate.go b/internal/pkg/sdk3rd/bunny/api_add_custom_certificate.go new file mode 100644 index 00000000..5950928d --- /dev/null +++ b/internal/pkg/sdk3rd/bunny/api_add_custom_certificate.go @@ -0,0 +1,38 @@ +package bunny + +import ( + "context" + "fmt" + "net/http" + "net/url" +) + +type AddCustomCertificateRequest struct { + Hostname string `json:"Hostname"` + Certificate string `json:"Certificate"` + CertificateKey string `json:"CertificateKey"` +} + +func (c *Client) AddCustomCertificate(pullZoneId string, req *AddCustomCertificateRequest) error { + return c.AddCustomCertificateWithContext(context.Background(), pullZoneId, req) +} + +func (c *Client) AddCustomCertificateWithContext(ctx context.Context, pullZoneId string, req *AddCustomCertificateRequest) error { + if pullZoneId == "" { + return fmt.Errorf("sdkerr: unset pullZoneId") + } + + httpreq, err := c.newRequest(http.MethodPost, fmt.Sprintf("/pullzone/%s/addCertificate", url.PathEscape(pullZoneId))) + if err != nil { + return err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + if _, err := c.doRequest(httpreq); err != nil { + return err + } + + return nil +} diff --git a/internal/pkg/sdk3rd/bunny/client.go b/internal/pkg/sdk3rd/bunny/client.go index 1efa2236..4382164e 100644 --- a/internal/pkg/sdk3rd/bunny/client.go +++ b/internal/pkg/sdk3rd/bunny/client.go @@ -1,10 +1,7 @@ package bunny import ( - "encoding/json" "fmt" - "net/http" - "strings" "time" "github.com/go-resty/resty/v2" @@ -14,47 +11,53 @@ type Client struct { client *resty.Client } -func NewClient(apiToken string) *Client { +func NewClient(apiToken string) (*Client, error) { + if apiToken == "" { + return nil, fmt.Errorf("sdkerr: unset apiToken") + } + client := resty.New(). SetBaseURL("https://api.bunny.net"). + SetHeader("Accept", "application/json"). + SetHeader("Content-Type", "application/json"). SetHeader("User-Agent", "certimate"). SetHeader("AccessKey", apiToken) - return &Client{ - client: client, - } + return &Client{client}, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { +func (c *Client) SetTimeout(timeout time.Duration) *Client { c.client.SetTimeout(timeout) return c } -func (c *Client) sendRequest(method string, path string, params interface{}) (*resty.Response, error) { - req := c.client.R() - if strings.EqualFold(method, http.MethodGet) { - qs := make(map[string]string) - if params != nil { - temp := make(map[string]any) - jsonb, _ := json.Marshal(params) - json.Unmarshal(jsonb, &temp) - for k, v := range temp { - if v != nil { - qs[k] = fmt.Sprintf("%v", v) - } - } - } - - req = req.SetQueryParams(qs) - } else { - req = req.SetHeader("Content-Type", "application/json").SetBody(params) +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") } - resp, err := req.Execute(method, path) + req := c.client.R() + req.Method = method + req.URL = path + return req, nil +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + // WARN: + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. + + resp, err := req.Send() if err != nil { - return resp, fmt.Errorf("bunny api error: failed to send request: %w", err) + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) } else if resp.IsError() { - return resp, fmt.Errorf("bunny api error: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) } return resp, nil diff --git a/internal/pkg/sdk3rd/bunny/models.go b/internal/pkg/sdk3rd/bunny/models.go deleted file mode 100644 index 3920eba1..00000000 --- a/internal/pkg/sdk3rd/bunny/models.go +++ /dev/null @@ -1,8 +0,0 @@ -package bunny - -type AddCustomCertificateRequest struct { - Hostname string `json:"Hostname"` - PullZoneId string `json:"-"` - Certificate string `json:"Certificate"` - CertificateKey string `json:"CertificateKey"` -} diff --git a/internal/pkg/sdk3rd/cachefly/api.go b/internal/pkg/sdk3rd/cachefly/api.go deleted file mode 100644 index 0b4ae265..00000000 --- a/internal/pkg/sdk3rd/cachefly/api.go +++ /dev/null @@ -1,11 +0,0 @@ -package cachefly - -import ( - "net/http" -) - -func (c *Client) CreateCertificate(req *CreateCertificateRequest) (*CreateCertificateResponse, error) { - resp := &CreateCertificateResponse{} - err := c.sendRequestWithResult(http.MethodPost, "/certificates", req, resp) - return resp, err -} diff --git a/internal/pkg/sdk3rd/cachefly/api_create_certificate.go b/internal/pkg/sdk3rd/cachefly/api_create_certificate.go new file mode 100644 index 00000000..833141dc --- /dev/null +++ b/internal/pkg/sdk3rd/cachefly/api_create_certificate.go @@ -0,0 +1,50 @@ +package cachefly + +import ( + "context" + "net/http" +) + +type CreateCertificateRequest struct { + Certificate *string `json:"certificate,omitempty"` + CertificateKey *string `json:"certificateKey,omitempty"` + Password *string `json:"password,omitempty"` +} + +type CreateCertificateResponse struct { + apiResponseBase + + Id string `json:"_id"` + SubjectCommonName string `json:"subjectCommonName"` + SubjectNames []string `json:"subjectNames"` + Expired bool `json:"expired"` + Expiring bool `json:"expiring"` + InUse bool `json:"inUse"` + Managed bool `json:"managed"` + Services []string `json:"services"` + Domains []string `json:"domains"` + NotBefore string `json:"notBefore"` + NotAfter string `json:"notAfter"` + CreatedAt string `json:"createdAt"` +} + +func (c *Client) CreateCertificate(req *CreateCertificateRequest) (*CreateCertificateResponse, error) { + return c.CreateCertificateWithContext(context.Background(), req) +} + +func (c *Client) CreateCertificateWithContext(ctx context.Context, req *CreateCertificateRequest) (*CreateCertificateResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/certificates") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &CreateCertificateResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/cachefly/client.go b/internal/pkg/sdk3rd/cachefly/client.go index cf29e833..ecce8161 100644 --- a/internal/pkg/sdk3rd/cachefly/client.go +++ b/internal/pkg/sdk3rd/cachefly/client.go @@ -3,8 +3,6 @@ package cachefly import ( "encoding/json" "fmt" - "net/http" - "strings" "time" "github.com/go-resty/resty/v2" @@ -14,63 +12,76 @@ type Client struct { client *resty.Client } -func NewClient(apiToken string) *Client { +func NewClient(apiToken string) (*Client, error) { + if apiToken == "" { + return nil, fmt.Errorf("sdkerr: unset apiToken") + } + client := resty.New(). SetBaseURL("https://api.cachefly.com/api/2.5"). + SetHeader("Accept", "application/json"). + SetHeader("Content-Type", "application/json"). + SetHeader("User-Agent", "certimate"). SetHeader("X-CF-Authorization", "Bearer "+apiToken) - return &Client{ - client: client, - } + return &Client{client}, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { +func (c *Client) SetTimeout(timeout time.Duration) *Client { c.client.SetTimeout(timeout) return c } -func (c *Client) sendRequest(method string, path string, params interface{}) (*resty.Response, error) { - req := c.client.R() - if strings.EqualFold(method, http.MethodGet) { - qs := make(map[string]string) - if params != nil { - temp := make(map[string]any) - jsonb, _ := json.Marshal(params) - json.Unmarshal(jsonb, &temp) - for k, v := range temp { - if v != nil { - qs[k] = fmt.Sprintf("%v", v) - } - } - } - - req = req.SetQueryParams(qs) - } else { - req = req.SetHeader("Content-Type", "application/json").SetBody(params) +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") } - resp, err := req.Execute(method, path) + req := c.client.R() + req.Method = method + req.URL = path + return req, nil +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + // WARN: + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. + + resp, err := req.Send() if err != nil { - return resp, fmt.Errorf("cachefly api error: failed to send request: %w", err) + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) } else if resp.IsError() { - return resp, fmt.Errorf("cachefly api error: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) } return resp, nil } -func (c *Client) sendRequestWithResult(method string, path string, params interface{}, result BaseResponse) error { - resp, err := c.sendRequest(method, path, params) +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + resp, err := c.doRequest(req) if err != nil { if resp != nil { - json.Unmarshal(resp.Body(), &result) + json.Unmarshal(resp.Body(), &res) } - return err + return resp, err } - if err := json.Unmarshal(resp.Body(), &result); err != nil { - return fmt.Errorf("cachefly api error: failed to unmarshal response: %w", err) + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) + } } - return nil + return resp, nil } diff --git a/internal/pkg/sdk3rd/cachefly/models.go b/internal/pkg/sdk3rd/cachefly/models.go deleted file mode 100644 index bcab441a..00000000 --- a/internal/pkg/sdk3rd/cachefly/models.go +++ /dev/null @@ -1,38 +0,0 @@ -package cachefly - -type BaseResponse interface { - GetMessage() string -} - -type baseResponse struct { - Message *string `json:"message,omitempty"` -} - -func (r *baseResponse) GetMessage() string { - if r.Message != nil { - return *r.Message - } - return "" -} - -type CreateCertificateRequest struct { - Certificate string `json:"certificate"` - CertificateKey string `json:"certificateKey"` - Password *string `json:"password"` -} - -type CreateCertificateResponse struct { - baseResponse - Id string `json:"_id"` - SubjectCommonName string `json:"subjectCommonName"` - SubjectNames []string `json:"subjectNames"` - Expired bool `json:"expired"` - Expiring bool `json:"expiring"` - InUse bool `json:"inUse"` - Managed bool `json:"managed"` - Services []string `json:"services"` - Domains []string `json:"domains"` - NotBefore string `json:"notBefore"` - NotAfter string `json:"notAfter"` - CreatedAt string `json:"createdAt"` -} diff --git a/internal/pkg/sdk3rd/cachefly/types.go b/internal/pkg/sdk3rd/cachefly/types.go new file mode 100644 index 00000000..98b39dfa --- /dev/null +++ b/internal/pkg/sdk3rd/cachefly/types.go @@ -0,0 +1,19 @@ +package cachefly + +type apiResponse interface { + GetMessage() string +} + +type apiResponseBase struct { + Message *string `json:"message,omitempty"` +} + +func (r *apiResponseBase) GetMessage() string { + if r.Message == nil { + return "" + } + + return *r.Message +} + +var _ apiResponse = (*apiResponseBase)(nil) diff --git a/internal/pkg/sdk3rd/cdnfly/api.go b/internal/pkg/sdk3rd/cdnfly/api.go deleted file mode 100644 index ee827b8c..00000000 --- a/internal/pkg/sdk3rd/cdnfly/api.go +++ /dev/null @@ -1,43 +0,0 @@ -package cdnfly - -import ( - "fmt" - "net/http" - "net/url" -) - -func (c *Client) GetSite(req *GetSiteRequest) (*GetSiteResponse, error) { - if req.Id == "" { - return nil, fmt.Errorf("cdnfly api error: invalid parameter: Id") - } - - resp := &GetSiteResponse{} - err := c.sendRequestWithResult(http.MethodGet, fmt.Sprintf("/v1/sites/%s", url.PathEscape(req.Id)), req, resp) - return resp, err -} - -func (c *Client) UpdateSite(req *UpdateSiteRequest) (*UpdateSiteResponse, error) { - if req.Id == "" { - return nil, fmt.Errorf("cdnfly api error: invalid parameter: Id") - } - - resp := &UpdateSiteResponse{} - err := c.sendRequestWithResult(http.MethodPut, fmt.Sprintf("/v1/sites/%s", url.PathEscape(req.Id)), req, resp) - return resp, err -} - -func (c *Client) CreateCertificate(req *CreateCertificateRequest) (*CreateCertificateResponse, error) { - resp := &CreateCertificateResponse{} - err := c.sendRequestWithResult(http.MethodPost, "/v1/certs", req, resp) - return resp, err -} - -func (c *Client) UpdateCertificate(req *UpdateCertificateRequest) (*UpdateCertificateResponse, error) { - if req.Id == "" { - return nil, fmt.Errorf("cdnfly api error: invalid parameter: Id") - } - - resp := &UpdateCertificateResponse{} - err := c.sendRequestWithResult(http.MethodPut, fmt.Sprintf("/v1/certs/%s", url.PathEscape(req.Id)), req, resp) - return resp, err -} diff --git a/internal/pkg/sdk3rd/cdnfly/api_create_cert.go b/internal/pkg/sdk3rd/cdnfly/api_create_cert.go new file mode 100644 index 00000000..3dcd9558 --- /dev/null +++ b/internal/pkg/sdk3rd/cdnfly/api_create_cert.go @@ -0,0 +1,41 @@ +package cdnfly + +import ( + "context" + "net/http" +) + +type CreateCertRequest struct { + Name *string `json:"name,omitempty"` + Description *string `json:"des,omitempty"` + Type *string `json:"type,omitempty"` + Cert *string `json:"cert,omitempty"` + Key *string `json:"key,omitempty"` +} + +type CreateCertResponse struct { + apiResponseBase + + Data string `json:"data"` +} + +func (c *Client) CreateCert(req *CreateCertRequest) (*CreateCertResponse, error) { + return c.CreateCertWithContext(context.Background(), req) +} + +func (c *Client) CreateCertWithContext(ctx context.Context, req *CreateCertRequest) (*CreateCertResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/certs") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &CreateCertResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/cdnfly/api_get_site.go b/internal/pkg/sdk3rd/cdnfly/api_get_site.go new file mode 100644 index 00000000..50d45d7c --- /dev/null +++ b/internal/pkg/sdk3rd/cdnfly/api_get_site.go @@ -0,0 +1,43 @@ +package cdnfly + +import ( + "context" + "fmt" + "net/http" + "net/url" +) + +type GetSiteResponse struct { + apiResponseBase + + Data *struct { + Id int64 `json:"id"` + Name string `json:"name"` + Domain string `json:"domain"` + HttpsListen string `json:"https_listen"` + } `json:"data,omitempty"` +} + +func (c *Client) GetSite(siteId string) (*GetSiteResponse, error) { + return c.GetSiteWithContext(context.Background(), siteId) +} + +func (c *Client) GetSiteWithContext(ctx context.Context, siteId string) (*GetSiteResponse, error) { + if siteId == "" { + return nil, fmt.Errorf("sdkerr: unset siteId") + } + + httpreq, err := c.newRequest(http.MethodGet, fmt.Sprintf("/sites/%s", url.PathEscape(siteId))) + if err != nil { + return nil, err + } else { + httpreq.SetContext(ctx) + } + + result := &GetSiteResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/cdnfly/api_update_cert.go b/internal/pkg/sdk3rd/cdnfly/api_update_cert.go new file mode 100644 index 00000000..9ad676ee --- /dev/null +++ b/internal/pkg/sdk3rd/cdnfly/api_update_cert.go @@ -0,0 +1,46 @@ +package cdnfly + +import ( + "context" + "fmt" + "net/http" + "net/url" +) + +type UpdateCertRequest struct { + Name *string `json:"name,omitempty"` + Description *string `json:"des,omitempty"` + Type *string `json:"type,omitempty"` + Cert *string `json:"cert,omitempty"` + Key *string `json:"key,omitempty"` + Enable *bool `json:"enable,omitempty"` +} + +type UpdateCertResponse struct { + apiResponseBase +} + +func (c *Client) UpdateCert(certId string, req *UpdateCertRequest) (*UpdateCertResponse, error) { + return c.UpdateCertWithContext(context.Background(), certId, req) +} + +func (c *Client) UpdateCertWithContext(ctx context.Context, certId string, req *UpdateCertRequest) (*UpdateCertResponse, error) { + if certId == "" { + return nil, fmt.Errorf("sdkerr: unset certId") + } + + httpreq, err := c.newRequest(http.MethodPut, fmt.Sprintf("/certs/%s", url.PathEscape(certId))) + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &UpdateCertResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/cdnfly/api_update_site.go b/internal/pkg/sdk3rd/cdnfly/api_update_site.go new file mode 100644 index 00000000..2a0ede20 --- /dev/null +++ b/internal/pkg/sdk3rd/cdnfly/api_update_site.go @@ -0,0 +1,42 @@ +package cdnfly + +import ( + "context" + "fmt" + "net/http" + "net/url" +) + +type UpdateSiteRequest struct { + HttpsListen *string `json:"https_listen,omitempty"` + Enable *bool `json:"enable,omitempty"` +} + +type UpdateSiteResponse struct { + apiResponseBase +} + +func (c *Client) UpdateSite(siteId string, req *UpdateSiteRequest) (*UpdateSiteResponse, error) { + return c.UpdateSiteWithContext(context.Background(), siteId, req) +} + +func (c *Client) UpdateSiteWithContext(ctx context.Context, siteId string, req *UpdateSiteRequest) (*UpdateSiteResponse, error) { + if siteId == "" { + return nil, fmt.Errorf("sdkerr: unset siteId") + } + + httpreq, err := c.newRequest(http.MethodPut, fmt.Sprintf("/sites/%s", url.PathEscape(siteId))) + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &UpdateSiteResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/cdnfly/client.go b/internal/pkg/sdk3rd/cdnfly/client.go index 6026d246..7bd98613 100644 --- a/internal/pkg/sdk3rd/cdnfly/client.go +++ b/internal/pkg/sdk3rd/cdnfly/client.go @@ -4,7 +4,7 @@ import ( "crypto/tls" "encoding/json" "fmt" - "net/http" + "net/url" "strings" "time" @@ -15,72 +15,95 @@ type Client struct { client *resty.Client } -func NewClient(serverUrl, apiKey, apiSecret string) *Client { +func NewClient(serverUrl, apiKey, apiSecret string) (*Client, error) { + if serverUrl == "" { + return nil, fmt.Errorf("sdkerr: unset serverUrl") + } + if _, err := url.Parse(serverUrl); err != nil { + return nil, fmt.Errorf("sdkerr: invalid serverUrl: %w", err) + } + if apiKey == "" { + return nil, fmt.Errorf("sdkerr: unset apiKey") + } + if apiSecret == "" { + return nil, fmt.Errorf("sdkerr: unset apiSecret") + } + client := resty.New(). - SetBaseURL(strings.TrimRight(serverUrl, "/")). + SetBaseURL(strings.TrimRight(serverUrl, "/")+"/v1"). + SetHeader("Accept", "application/json"). + SetHeader("Content-Type", "application/json"). SetHeader("User-Agent", "certimate"). SetHeader("API-Key", apiKey). SetHeader("API-Secret", apiSecret) - return &Client{ - client: client, - } + return &Client{client}, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { +func (c *Client) SetTimeout(timeout time.Duration) *Client { c.client.SetTimeout(timeout) return c } -func (c *Client) WithTLSConfig(config *tls.Config) *Client { +func (c *Client) SetTLSConfig(config *tls.Config) *Client { c.client.SetTLSClientConfig(config) return c } -func (c *Client) sendRequest(method string, path string, params interface{}) (*resty.Response, error) { - req := c.client.R() - if strings.EqualFold(method, http.MethodGet) { - qs := make(map[string]string) - if params != nil { - temp := make(map[string]any) - jsonb, _ := json.Marshal(params) - json.Unmarshal(jsonb, &temp) - for k, v := range temp { - if v != nil { - qs[k] = fmt.Sprintf("%v", v) - } - } - } - - req = req.SetQueryParams(qs) - } else { - req = req.SetHeader("Content-Type", "application/json").SetBody(params) +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") } - resp, err := req.Execute(method, path) + req := c.client.R() + req.Method = method + req.URL = path + return req, nil +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + // WARN: + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. + + resp, err := req.Send() if err != nil { - return resp, fmt.Errorf("cdnfly api error: failed to send request: %w", err) + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) } else if resp.IsError() { - return resp, fmt.Errorf("cdnfly api error: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) } return resp, nil } -func (c *Client) sendRequestWithResult(method string, path string, params interface{}, result BaseResponse) error { - resp, err := c.sendRequest(method, path, params) +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + resp, err := c.doRequest(req) if err != nil { if resp != nil { - json.Unmarshal(resp.Body(), &result) + json.Unmarshal(resp.Body(), &res) } - return err + return resp, err } - if err := json.Unmarshal(resp.Body(), &result); err != nil { - return fmt.Errorf("cdnfly api error: failed to unmarshal response: %w", err) - } else if errcode := result.GetCode(); errcode != "" && errcode != "0" { - return fmt.Errorf("cdnfly api error: code='%s', message='%s'", errcode, result.GetMessage()) + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) + } else { + if tcode := res.GetCode(); tcode != "" && tcode != "0" { + return resp, fmt.Errorf("sdkerr: code='%s', message='%s'", tcode, res.GetMessage()) + } + } } - return nil + return resp, nil } diff --git a/internal/pkg/sdk3rd/cdnfly/models.go b/internal/pkg/sdk3rd/cdnfly/models.go deleted file mode 100644 index d676becd..00000000 --- a/internal/pkg/sdk3rd/cdnfly/models.go +++ /dev/null @@ -1,84 +0,0 @@ -package cdnfly - -import "fmt" - -type BaseResponse interface { - GetCode() string - GetMessage() string -} - -type baseResponse struct { - Code any `json:"code"` - Message string `json:"msg"` -} - -func (r *baseResponse) GetCode() string { - if r.Code == nil { - return "" - } - - if code, ok := r.Code.(int); ok { - return fmt.Sprintf("%d", code) - } - - if code, ok := r.Code.(string); ok { - return code - } - - return "" -} - -func (r *baseResponse) GetMessage() string { - return r.Message -} - -type GetSiteRequest struct { - Id string `json:"-"` -} - -type GetSiteResponse struct { - baseResponse - Data *struct { - Id int64 `json:"id"` - Name string `json:"name"` - Domain string `json:"domain"` - HttpsListen string `json:"https_listen"` - } `json:"data,omitempty"` -} - -type UpdateSiteRequest struct { - Id string `json:"-"` - HttpsListen *string `json:"https_listen,omitempty"` - Enable *bool `json:"enable,omitempty"` -} - -type UpdateSiteResponse struct { - baseResponse -} - -type CreateCertificateRequest struct { - Name string `json:"name"` - Description *string `json:"des,omitempty"` - Type string `json:"type"` - Cert string `json:"cert"` - Key string `json:"key"` -} - -type CreateCertificateResponse struct { - baseResponse - Data string `json:"data"` -} - -type UpdateCertificateRequest struct { - Id string `json:"-"` - Name *string `json:"name,omitempty"` - Description *string `json:"des,omitempty"` - Type *string `json:"type,omitempty"` - Cert *string `json:"cert,omitempty"` - Key *string `json:"key,omitempty"` - Enable *bool `json:"enable,omitempty"` -} - -type UpdateCertificateResponse struct { - baseResponse -} diff --git a/internal/pkg/sdk3rd/cdnfly/types.go b/internal/pkg/sdk3rd/cdnfly/types.go new file mode 100644 index 00000000..fff2c271 --- /dev/null +++ b/internal/pkg/sdk3rd/cdnfly/types.go @@ -0,0 +1,46 @@ +package cdnfly + +import ( + "bytes" + "encoding/json" + "strconv" +) + +type apiResponse interface { + GetCode() string + GetMessage() string +} + +type apiResponseBase struct { + Code json.RawMessage `json:"code"` + Message string `json:"msg"` +} + +func (r *apiResponseBase) GetCode() string { + if r.Code == nil { + return "" + } + + decoder := json.NewDecoder(bytes.NewReader(r.Code)) + token, err := decoder.Token() + if err != nil { + return "" + } + + switch t := token.(type) { + case string: + return t + case float64: + return strconv.FormatFloat(t, 'f', -1, 64) + case json.Number: + return t.String() + default: + return "" + } +} + +func (r *apiResponseBase) GetMessage() string { + return r.Message +} + +var _ apiResponse = (*apiResponseBase)(nil) diff --git a/internal/pkg/sdk3rd/ctyun/ao/api_create_cert.go b/internal/pkg/sdk3rd/ctyun/ao/api_create_cert.go index 1a9ac21e..eecc7267 100644 --- a/internal/pkg/sdk3rd/ctyun/ao/api_create_cert.go +++ b/internal/pkg/sdk3rd/ctyun/ao/api_create_cert.go @@ -12,7 +12,7 @@ type CreateCertRequest struct { } type CreateCertResponse struct { - baseResult + apiResponseBase ReturnObj *struct { Id int64 `json:"id"` diff --git a/internal/pkg/sdk3rd/ctyun/ao/api_get_domain_config.go b/internal/pkg/sdk3rd/ctyun/ao/api_get_domain_config.go index c7b639f4..01c007ab 100644 --- a/internal/pkg/sdk3rd/ctyun/ao/api_get_domain_config.go +++ b/internal/pkg/sdk3rd/ctyun/ao/api_get_domain_config.go @@ -11,7 +11,7 @@ type GetDomainConfigRequest struct { } type GetDomainConfigResponse struct { - baseResult + apiResponseBase ReturnObj *struct { Domain string `json:"domain"` @@ -35,13 +35,7 @@ func (c *Client) GetDomainConfigWithContext(ctx context.Context, req *GetDomainC if err != nil { return nil, err } else { - if req.Domain != nil { - httpreq.SetQueryParam("domain", *req.Domain) - } - if req.ProductCode != nil { - httpreq.SetQueryParam("product_code", *req.ProductCode) - } - + httpreq.SetBody(req) httpreq.SetContext(ctx) } diff --git a/internal/pkg/sdk3rd/ctyun/ao/api_list_certs.go b/internal/pkg/sdk3rd/ctyun/ao/api_list_certs.go index 70ba7036..a77cd377 100644 --- a/internal/pkg/sdk3rd/ctyun/ao/api_list_certs.go +++ b/internal/pkg/sdk3rd/ctyun/ao/api_list_certs.go @@ -13,7 +13,7 @@ type ListCertsRequest struct { } type ListCertsResponse struct { - baseResult + apiResponseBase ReturnObj *struct { Results []*CertRecord `json:"result,omitempty"` diff --git a/internal/pkg/sdk3rd/ctyun/ao/api_modify_domain_config.go b/internal/pkg/sdk3rd/ctyun/ao/api_modify_domain_config.go index f28b3dc9..ef407e99 100644 --- a/internal/pkg/sdk3rd/ctyun/ao/api_modify_domain_config.go +++ b/internal/pkg/sdk3rd/ctyun/ao/api_modify_domain_config.go @@ -15,7 +15,7 @@ type ModifyDomainConfigRequest struct { } type ModifyDomainConfigResponse struct { - baseResult + apiResponseBase } func (c *Client) ModifyDomainConfig(req *ModifyDomainConfigRequest) (*ModifyDomainConfigResponse, error) { diff --git a/internal/pkg/sdk3rd/ctyun/ao/api_query_cert.go b/internal/pkg/sdk3rd/ctyun/ao/api_query_cert.go index 9ec2d740..3493cdbe 100644 --- a/internal/pkg/sdk3rd/ctyun/ao/api_query_cert.go +++ b/internal/pkg/sdk3rd/ctyun/ao/api_query_cert.go @@ -13,7 +13,7 @@ type QueryCertRequest struct { } type QueryCertResponse struct { - baseResult + apiResponseBase ReturnObj *struct { Result *CertDetail `json:"result,omitempty"` diff --git a/internal/pkg/sdk3rd/ctyun/ao/client.go b/internal/pkg/sdk3rd/ctyun/ao/client.go index dbf20321..7673fd61 100644 --- a/internal/pkg/sdk3rd/ctyun/ao/client.go +++ b/internal/pkg/sdk3rd/ctyun/ao/client.go @@ -32,18 +32,17 @@ func (c *Client) newRequest(method string, path string) (*resty.Request, error) return c.client.NewRequest(method, path) } -func (c *Client) doRequest(request *resty.Request) (*resty.Response, error) { - return c.client.DoRequest(request) +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + return c.client.DoRequest(req) } -func (c *Client) doRequestWithResult(request *resty.Request, result baseResultInterface) (*resty.Response, error) { - response, err := c.client.DoRequestWithResult(request, result) +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + resp, err := c.client.DoRequestWithResult(req, res) if err == nil { - statusCode := result.GetStatusCode() - if statusCode != "" && statusCode != "100000" { - return response, fmt.Errorf("sdkerr: api error, code='%s', message='%s', errorCode='%s', errorMessage='%s'", statusCode, result.GetMessage(), result.GetMessage(), result.GetErrorMessage()) + if tcode := res.GetStatusCode(); tcode != "" && tcode != "100000" { + return resp, fmt.Errorf("sdkerr: api error, code='%s', message='%s', errorCode='%s', errorMessage='%s'", tcode, res.GetMessage(), res.GetMessage(), res.GetErrorMessage()) } } - return response, err + return resp, err } diff --git a/internal/pkg/sdk3rd/ctyun/ao/types.go b/internal/pkg/sdk3rd/ctyun/ao/types.go index ba5582b3..c706afd9 100644 --- a/internal/pkg/sdk3rd/ctyun/ao/types.go +++ b/internal/pkg/sdk3rd/ctyun/ao/types.go @@ -6,14 +6,14 @@ import ( "strconv" ) -type baseResultInterface interface { +type apiResponse interface { GetStatusCode() string GetMessage() string GetError() string GetErrorMessage() string } -type baseResult struct { +type apiResponseBase struct { StatusCode json.RawMessage `json:"statusCode,omitempty"` Message *string `json:"message,omitempty"` Error *string `json:"error,omitempty"` @@ -21,7 +21,7 @@ type baseResult struct { RequestId *string `json:"requestId,omitempty"` } -func (r *baseResult) GetStatusCode() string { +func (r *apiResponseBase) GetStatusCode() string { if r.StatusCode == nil { return "" } @@ -44,7 +44,7 @@ func (r *baseResult) GetStatusCode() string { } } -func (r *baseResult) GetMessage() string { +func (r *apiResponseBase) GetMessage() string { if r.Message == nil { return "" } @@ -52,7 +52,7 @@ func (r *baseResult) GetMessage() string { return *r.Message } -func (r *baseResult) GetError() string { +func (r *apiResponseBase) GetError() string { if r.Error == nil { return "" } @@ -60,7 +60,7 @@ func (r *baseResult) GetError() string { return *r.Error } -func (r *baseResult) GetErrorMessage() string { +func (r *apiResponseBase) GetErrorMessage() string { if r.ErrorMessage == nil { return "" } @@ -68,7 +68,7 @@ func (r *baseResult) GetErrorMessage() string { return *r.ErrorMessage } -var _ baseResultInterface = (*baseResult)(nil) +var _ apiResponse = (*apiResponseBase)(nil) type CertRecord struct { Id int64 `json:"id"` diff --git a/internal/pkg/sdk3rd/ctyun/cdn/api_create_cert.go b/internal/pkg/sdk3rd/ctyun/cdn/api_create_cert.go index 9445035b..33d45892 100644 --- a/internal/pkg/sdk3rd/ctyun/cdn/api_create_cert.go +++ b/internal/pkg/sdk3rd/ctyun/cdn/api_create_cert.go @@ -12,7 +12,7 @@ type CreateCertRequest struct { } type CreateCertResponse struct { - baseResult + apiResponseBase ReturnObj *struct { Id int64 `json:"id"` diff --git a/internal/pkg/sdk3rd/ctyun/cdn/api_query_cert_detail.go b/internal/pkg/sdk3rd/ctyun/cdn/api_query_cert_detail.go index 12501f29..a2998ea4 100644 --- a/internal/pkg/sdk3rd/ctyun/cdn/api_query_cert_detail.go +++ b/internal/pkg/sdk3rd/ctyun/cdn/api_query_cert_detail.go @@ -13,7 +13,7 @@ type QueryCertDetailRequest struct { } type QueryCertDetailResponse struct { - baseResult + apiResponseBase ReturnObj *struct { Result *CertDetail `json:"result,omitempty"` diff --git a/internal/pkg/sdk3rd/ctyun/cdn/api_query_cert_list.go b/internal/pkg/sdk3rd/ctyun/cdn/api_query_cert_list.go index 0f134594..3c09696d 100644 --- a/internal/pkg/sdk3rd/ctyun/cdn/api_query_cert_list.go +++ b/internal/pkg/sdk3rd/ctyun/cdn/api_query_cert_list.go @@ -13,7 +13,7 @@ type QueryCertListRequest struct { } type QueryCertListResponse struct { - baseResult + apiResponseBase ReturnObj *struct { Results []*CertRecord `json:"result,omitempty"` diff --git a/internal/pkg/sdk3rd/ctyun/cdn/api_query_domain_detail.go b/internal/pkg/sdk3rd/ctyun/cdn/api_query_domain_detail.go index 9a29b4f2..f66cc44a 100644 --- a/internal/pkg/sdk3rd/ctyun/cdn/api_query_domain_detail.go +++ b/internal/pkg/sdk3rd/ctyun/cdn/api_query_domain_detail.go @@ -12,7 +12,7 @@ type QueryDomainDetailRequest struct { } type QueryDomainDetailResponse struct { - baseResult + apiResponseBase ReturnObj *struct { Domain string `json:"domain"` diff --git a/internal/pkg/sdk3rd/ctyun/cdn/api_update_domain.go b/internal/pkg/sdk3rd/ctyun/cdn/api_update_domain.go index 65dd918c..5b90721e 100644 --- a/internal/pkg/sdk3rd/ctyun/cdn/api_update_domain.go +++ b/internal/pkg/sdk3rd/ctyun/cdn/api_update_domain.go @@ -12,7 +12,7 @@ type UpdateDomainRequest struct { } type UpdateDomainResponse struct { - baseResult + apiResponseBase } func (c *Client) UpdateDomain(req *UpdateDomainRequest) (*UpdateDomainResponse, error) { diff --git a/internal/pkg/sdk3rd/ctyun/cdn/client.go b/internal/pkg/sdk3rd/ctyun/cdn/client.go index 77402a4e..58060033 100644 --- a/internal/pkg/sdk3rd/ctyun/cdn/client.go +++ b/internal/pkg/sdk3rd/ctyun/cdn/client.go @@ -32,18 +32,17 @@ func (c *Client) newRequest(method string, path string) (*resty.Request, error) return c.client.NewRequest(method, path) } -func (c *Client) doRequest(request *resty.Request) (*resty.Response, error) { - return c.client.DoRequest(request) +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + return c.client.DoRequest(req) } -func (c *Client) doRequestWithResult(request *resty.Request, result baseResultInterface) (*resty.Response, error) { - response, err := c.client.DoRequestWithResult(request, result) +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + resp, err := c.client.DoRequestWithResult(req, res) if err == nil { - statusCode := result.GetStatusCode() - if statusCode != "" && statusCode != "100000" { - return response, fmt.Errorf("sdkerr: api error, code='%s', message='%s', errorCode='%s', errorMessage='%s'", statusCode, result.GetMessage(), result.GetMessage(), result.GetErrorMessage()) + if tcode := res.GetStatusCode(); tcode != "" && tcode != "100000" { + return resp, fmt.Errorf("sdkerr: api error, code='%s', message='%s', errorCode='%s', errorMessage='%s'", tcode, res.GetMessage(), res.GetMessage(), res.GetErrorMessage()) } } - return response, err + return resp, err } diff --git a/internal/pkg/sdk3rd/ctyun/cdn/types.go b/internal/pkg/sdk3rd/ctyun/cdn/types.go index 96c97ce1..32054a0c 100644 --- a/internal/pkg/sdk3rd/ctyun/cdn/types.go +++ b/internal/pkg/sdk3rd/ctyun/cdn/types.go @@ -6,14 +6,14 @@ import ( "strconv" ) -type baseResultInterface interface { +type apiResponse interface { GetStatusCode() string GetMessage() string GetError() string GetErrorMessage() string } -type baseResult struct { +type apiResponseBase struct { StatusCode json.RawMessage `json:"statusCode,omitempty"` Message *string `json:"message,omitempty"` Error *string `json:"error,omitempty"` @@ -21,7 +21,7 @@ type baseResult struct { RequestId *string `json:"requestId,omitempty"` } -func (r *baseResult) GetStatusCode() string { +func (r *apiResponseBase) GetStatusCode() string { if r.StatusCode == nil { return "" } @@ -44,7 +44,7 @@ func (r *baseResult) GetStatusCode() string { } } -func (r *baseResult) GetMessage() string { +func (r *apiResponseBase) GetMessage() string { if r.Message == nil { return "" } @@ -52,7 +52,7 @@ func (r *baseResult) GetMessage() string { return *r.Message } -func (r *baseResult) GetError() string { +func (r *apiResponseBase) GetError() string { if r.Error == nil { return "" } @@ -60,7 +60,7 @@ func (r *baseResult) GetError() string { return *r.Error } -func (r *baseResult) GetErrorMessage() string { +func (r *apiResponseBase) GetErrorMessage() string { if r.ErrorMessage == nil { return "" } @@ -68,7 +68,7 @@ func (r *baseResult) GetErrorMessage() string { return *r.ErrorMessage } -var _ baseResultInterface = (*baseResult)(nil) +var _ apiResponse = (*apiResponseBase)(nil) type CertRecord struct { Id int64 `json:"id"` diff --git a/internal/pkg/sdk3rd/ctyun/cms/api_get_certificate_list.go b/internal/pkg/sdk3rd/ctyun/cms/api_get_certificate_list.go index f410921f..a5de5a60 100644 --- a/internal/pkg/sdk3rd/ctyun/cms/api_get_certificate_list.go +++ b/internal/pkg/sdk3rd/ctyun/cms/api_get_certificate_list.go @@ -14,7 +14,7 @@ type GetCertificateListRequest struct { } type GetCertificateListResponse struct { - baseResult + apiResponseBase ReturnObj *struct { List []*CertificateRecord `json:"list,omitempty"` diff --git a/internal/pkg/sdk3rd/ctyun/cms/api_upload_certificate.go b/internal/pkg/sdk3rd/ctyun/cms/api_upload_certificate.go index 8044aa40..ed02a357 100644 --- a/internal/pkg/sdk3rd/ctyun/cms/api_upload_certificate.go +++ b/internal/pkg/sdk3rd/ctyun/cms/api_upload_certificate.go @@ -16,7 +16,7 @@ type UploadCertificateRequest struct { } type UploadCertificateResponse struct { - baseResult + apiResponseBase } func (c *Client) UploadCertificate(req *UploadCertificateRequest) (*UploadCertificateResponse, error) { diff --git a/internal/pkg/sdk3rd/ctyun/cms/client.go b/internal/pkg/sdk3rd/ctyun/cms/client.go index ac94d1b6..bf5606ea 100644 --- a/internal/pkg/sdk3rd/ctyun/cms/client.go +++ b/internal/pkg/sdk3rd/ctyun/cms/client.go @@ -32,19 +32,19 @@ func (c *Client) newRequest(method string, path string) (*resty.Request, error) return c.client.NewRequest(method, path) } -func (c *Client) doRequest(request *resty.Request) (*resty.Response, error) { - return c.client.DoRequest(request) +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + return c.client.DoRequest(req) } -func (c *Client) doRequestWithResult(request *resty.Request, result baseResultInterface) (*resty.Response, error) { - response, err := c.client.DoRequestWithResult(request, result) +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + resp, err := c.client.DoRequestWithResult(req, res) if err == nil { - statusCode := result.GetStatusCode() - errorCode := result.GetError() + statusCode := res.GetStatusCode() + errorCode := res.GetError() if (statusCode != "" && statusCode != "200") || errorCode != "" { - return response, fmt.Errorf("sdkerr: api error, code='%s', message='%s', errorCode='%s', errorMessage='%s'", statusCode, result.GetMessage(), result.GetMessage(), result.GetErrorMessage()) + return resp, fmt.Errorf("sdkerr: api error, code='%s', message='%s', errorCode='%s', errorMessage='%s'", statusCode, res.GetMessage(), res.GetMessage(), res.GetErrorMessage()) } } - return response, err + return resp, err } diff --git a/internal/pkg/sdk3rd/ctyun/cms/types.go b/internal/pkg/sdk3rd/ctyun/cms/types.go index b5b0b4d7..04a8c458 100644 --- a/internal/pkg/sdk3rd/ctyun/cms/types.go +++ b/internal/pkg/sdk3rd/ctyun/cms/types.go @@ -6,14 +6,14 @@ import ( "strconv" ) -type baseResultInterface interface { +type apiResponse interface { GetStatusCode() string GetMessage() string GetError() string GetErrorMessage() string } -type baseResult struct { +type apiResponseBase struct { StatusCode json.RawMessage `json:"statusCode,omitempty"` Message *string `json:"message,omitempty"` Error *string `json:"error,omitempty"` @@ -21,7 +21,7 @@ type baseResult struct { RequestId *string `json:"requestId,omitempty"` } -func (r *baseResult) GetStatusCode() string { +func (r *apiResponseBase) GetStatusCode() string { if r.StatusCode == nil { return "" } @@ -44,7 +44,7 @@ func (r *baseResult) GetStatusCode() string { } } -func (r *baseResult) GetMessage() string { +func (r *apiResponseBase) GetMessage() string { if r.Message == nil { return "" } @@ -52,7 +52,7 @@ func (r *baseResult) GetMessage() string { return *r.Message } -func (r *baseResult) GetError() string { +func (r *apiResponseBase) GetError() string { if r.Error == nil { return "" } @@ -60,7 +60,7 @@ func (r *baseResult) GetError() string { return *r.Error } -func (r *baseResult) GetErrorMessage() string { +func (r *apiResponseBase) GetErrorMessage() string { if r.ErrorMessage == nil { return "" } @@ -68,7 +68,7 @@ func (r *baseResult) GetErrorMessage() string { return *r.ErrorMessage } -var _ baseResultInterface = (*baseResult)(nil) +var _ apiResponse = (*apiResponseBase)(nil) type CertificateRecord struct { Id string `json:"id"` diff --git a/internal/pkg/sdk3rd/ctyun/dns/api_add_record.go b/internal/pkg/sdk3rd/ctyun/dns/api_add_record.go index 86227e5f..d2699dc3 100644 --- a/internal/pkg/sdk3rd/ctyun/dns/api_add_record.go +++ b/internal/pkg/sdk3rd/ctyun/dns/api_add_record.go @@ -17,7 +17,7 @@ type AddRecordRequest struct { } type AddRecordResponse struct { - baseResult + apiResponseBase ReturnObj *struct { RecordId int32 `json:"recordId"` diff --git a/internal/pkg/sdk3rd/ctyun/dns/api_delete_record.go b/internal/pkg/sdk3rd/ctyun/dns/api_delete_record.go index ad35a349..8a6cf033 100644 --- a/internal/pkg/sdk3rd/ctyun/dns/api_delete_record.go +++ b/internal/pkg/sdk3rd/ctyun/dns/api_delete_record.go @@ -10,7 +10,7 @@ type DeleteRecordRequest struct { } type DeleteRecordResponse struct { - baseResult + apiResponseBase } func (c *Client) DeleteRecord(req *DeleteRecordRequest) (*DeleteRecordResponse, error) { diff --git a/internal/pkg/sdk3rd/ctyun/dns/api_query_record_list.go b/internal/pkg/sdk3rd/ctyun/dns/api_query_record_list.go index d94afcde..cac3a6e3 100644 --- a/internal/pkg/sdk3rd/ctyun/dns/api_query_record_list.go +++ b/internal/pkg/sdk3rd/ctyun/dns/api_query_record_list.go @@ -3,6 +3,7 @@ package dns import ( "context" "net/http" + "strconv" ) type QueryRecordListRequest struct { @@ -15,7 +16,7 @@ type QueryRecordListRequest struct { } type QueryRecordListResponse struct { - baseResult + apiResponseBase ReturnObj *struct { Records []*DnsRecord `json:"records,omitempty"` @@ -31,6 +32,25 @@ func (c *Client) QueryRecordListWithContext(ctx context.Context, req *QueryRecor if err != nil { return nil, err } else { + if req.Domain != nil { + httpreq.SetQueryParam("domain", *req.Domain) + } + if req.Host != nil { + httpreq.SetQueryParam("host", *req.Host) + } + if req.Type != nil { + httpreq.SetQueryParam("type", *req.Type) + } + if req.LineCode != nil { + httpreq.SetQueryParam("lineCode", *req.LineCode) + } + if req.Value != nil { + httpreq.SetQueryParam("value", *req.Value) + } + if req.State != nil { + httpreq.SetQueryParam("state", strconv.Itoa(int(*req.State))) + } + httpreq.SetBody(req) httpreq.SetContext(ctx) } diff --git a/internal/pkg/sdk3rd/ctyun/dns/api_update_record.go b/internal/pkg/sdk3rd/ctyun/dns/api_update_record.go index e6dbdc7e..c84a0357 100644 --- a/internal/pkg/sdk3rd/ctyun/dns/api_update_record.go +++ b/internal/pkg/sdk3rd/ctyun/dns/api_update_record.go @@ -18,7 +18,7 @@ type UpdateRecordRequest struct { } type UpdateRecordResponse struct { - baseResult + apiResponseBase ReturnObj *struct { RecordId int32 `json:"recordId"` diff --git a/internal/pkg/sdk3rd/ctyun/dns/client.go b/internal/pkg/sdk3rd/ctyun/dns/client.go index 4e684bd8..98ee8100 100644 --- a/internal/pkg/sdk3rd/ctyun/dns/client.go +++ b/internal/pkg/sdk3rd/ctyun/dns/client.go @@ -32,19 +32,19 @@ func (c *Client) newRequest(method string, path string) (*resty.Request, error) return c.client.NewRequest(method, path) } -func (c *Client) doRequest(request *resty.Request) (*resty.Response, error) { - return c.client.DoRequest(request) +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + return c.client.DoRequest(req) } -func (c *Client) doRequestWithResult(request *resty.Request, result baseResultInterface) (*resty.Response, error) { - response, err := c.client.DoRequestWithResult(request, result) +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + resp, err := c.client.DoRequestWithResult(req, res) if err == nil { - statusCode := result.GetStatusCode() - errorCode := result.GetError() + statusCode := res.GetStatusCode() + errorCode := res.GetError() if (statusCode != "" && statusCode != "200") || errorCode != "" { - return response, fmt.Errorf("sdkerr: api error, code='%s', message='%s', errorCode='%s', errorMessage='%s'", statusCode, result.GetMessage(), result.GetMessage(), result.GetErrorMessage()) + return resp, fmt.Errorf("sdkerr: api error, code='%s', message='%s', errorCode='%s', errorMessage='%s'", statusCode, res.GetMessage(), res.GetMessage(), res.GetErrorMessage()) } } - return response, err + return resp, err } diff --git a/internal/pkg/sdk3rd/ctyun/dns/types.go b/internal/pkg/sdk3rd/ctyun/dns/types.go index 225f60d7..bd500938 100644 --- a/internal/pkg/sdk3rd/ctyun/dns/types.go +++ b/internal/pkg/sdk3rd/ctyun/dns/types.go @@ -6,14 +6,14 @@ import ( "strconv" ) -type baseResultInterface interface { +type apiResponse interface { GetStatusCode() string GetMessage() string GetError() string GetErrorMessage() string } -type baseResult struct { +type apiResponseBase struct { StatusCode json.RawMessage `json:"statusCode,omitempty"` Message *string `json:"message,omitempty"` Error *string `json:"error,omitempty"` @@ -21,7 +21,7 @@ type baseResult struct { RequestId *string `json:"requestId,omitempty"` } -func (r *baseResult) GetStatusCode() string { +func (r *apiResponseBase) GetStatusCode() string { if r.StatusCode == nil { return "" } @@ -44,7 +44,7 @@ func (r *baseResult) GetStatusCode() string { } } -func (r *baseResult) GetMessage() string { +func (r *apiResponseBase) GetMessage() string { if r.Message == nil { return "" } @@ -52,7 +52,7 @@ func (r *baseResult) GetMessage() string { return *r.Message } -func (r *baseResult) GetError() string { +func (r *apiResponseBase) GetError() string { if r.Error == nil { return "" } @@ -60,7 +60,7 @@ func (r *baseResult) GetError() string { return *r.Error } -func (r *baseResult) GetErrorMessage() string { +func (r *apiResponseBase) GetErrorMessage() string { if r.ErrorMessage == nil { return "" } @@ -68,7 +68,7 @@ func (r *baseResult) GetErrorMessage() string { return *r.ErrorMessage } -var _ baseResultInterface = (*baseResult)(nil) +var _ apiResponse = (*apiResponseBase)(nil) type DnsRecord struct { RecordId int32 `json:"recordId"` diff --git a/internal/pkg/sdk3rd/ctyun/elb/api_create_certificate.go b/internal/pkg/sdk3rd/ctyun/elb/api_create_certificate.go index af17cdb7..4ea78f7a 100644 --- a/internal/pkg/sdk3rd/ctyun/elb/api_create_certificate.go +++ b/internal/pkg/sdk3rd/ctyun/elb/api_create_certificate.go @@ -16,7 +16,7 @@ type CreateCertificateRequest struct { } type CreateCertificateResponse struct { - baseResult + apiResponseBase ReturnObj *struct { ID string `json:"id"` diff --git a/internal/pkg/sdk3rd/ctyun/elb/api_list_certificates.go b/internal/pkg/sdk3rd/ctyun/elb/api_list_certificates.go index 6ba1b5a7..e7256126 100644 --- a/internal/pkg/sdk3rd/ctyun/elb/api_list_certificates.go +++ b/internal/pkg/sdk3rd/ctyun/elb/api_list_certificates.go @@ -14,7 +14,7 @@ type ListCertificatesRequest struct { } type ListCertificatesResponse struct { - baseResult + apiResponseBase ReturnObj []*CertificateRecord `json:"returnObj,omitempty"` } diff --git a/internal/pkg/sdk3rd/ctyun/elb/api_list_listeners.go b/internal/pkg/sdk3rd/ctyun/elb/api_list_listeners.go index 404c4399..9de6b0ce 100644 --- a/internal/pkg/sdk3rd/ctyun/elb/api_list_listeners.go +++ b/internal/pkg/sdk3rd/ctyun/elb/api_list_listeners.go @@ -16,7 +16,7 @@ type ListListenersRequest struct { } type ListListenersResponse struct { - baseResult + apiResponseBase ReturnObj []*ListenerRecord `json:"returnObj,omitempty"` } diff --git a/internal/pkg/sdk3rd/ctyun/elb/api_show_listener.go b/internal/pkg/sdk3rd/ctyun/elb/api_show_listener.go index a57a8bea..2d1ad02f 100644 --- a/internal/pkg/sdk3rd/ctyun/elb/api_show_listener.go +++ b/internal/pkg/sdk3rd/ctyun/elb/api_show_listener.go @@ -12,7 +12,7 @@ type ShowListenerRequest struct { } type ShowListenerResponse struct { - baseResult + apiResponseBase ReturnObj []*ListenerRecord `json:"returnObj,omitempty"` } diff --git a/internal/pkg/sdk3rd/ctyun/elb/api_update_listener.go b/internal/pkg/sdk3rd/ctyun/elb/api_update_listener.go index 845d9100..8cb2f425 100644 --- a/internal/pkg/sdk3rd/ctyun/elb/api_update_listener.go +++ b/internal/pkg/sdk3rd/ctyun/elb/api_update_listener.go @@ -17,7 +17,7 @@ type UpdateListenerRequest struct { } type UpdateListenerResponse struct { - baseResult + apiResponseBase ReturnObj []*ListenerRecord `json:"returnObj,omitempty"` } diff --git a/internal/pkg/sdk3rd/ctyun/elb/client.go b/internal/pkg/sdk3rd/ctyun/elb/client.go index a71effa3..0bcf8322 100644 --- a/internal/pkg/sdk3rd/ctyun/elb/client.go +++ b/internal/pkg/sdk3rd/ctyun/elb/client.go @@ -32,19 +32,19 @@ func (c *Client) newRequest(method string, path string) (*resty.Request, error) return c.client.NewRequest(method, path) } -func (c *Client) doRequest(request *resty.Request) (*resty.Response, error) { - return c.client.DoRequest(request) +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + return c.client.DoRequest(req) } -func (c *Client) doRequestWithResult(request *resty.Request, result baseResultInterface) (*resty.Response, error) { - response, err := c.client.DoRequestWithResult(request, result) +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + resp, err := c.client.DoRequestWithResult(req, res) if err == nil { - statusCode := result.GetStatusCode() - errorCode := result.GetError() + statusCode := res.GetStatusCode() + errorCode := res.GetError() if (statusCode != "" && statusCode != "200" && statusCode != "800") || (errorCode != "" && errorCode != "SUCCESS") { - return response, fmt.Errorf("sdkerr: api error, code='%s', message='%s', errorCode='%s', description='%s'", statusCode, result.GetMessage(), result.GetMessage(), result.GetDescription()) + return resp, fmt.Errorf("sdkerr: api error, code='%s', message='%s', errorCode='%s', description='%s'", statusCode, res.GetMessage(), res.GetMessage(), res.GetDescription()) } } - return response, err + return resp, err } diff --git a/internal/pkg/sdk3rd/ctyun/elb/types.go b/internal/pkg/sdk3rd/ctyun/elb/types.go index 4f2971b8..ed64d0fa 100644 --- a/internal/pkg/sdk3rd/ctyun/elb/types.go +++ b/internal/pkg/sdk3rd/ctyun/elb/types.go @@ -6,14 +6,14 @@ import ( "strconv" ) -type baseResultInterface interface { +type apiResponse interface { GetStatusCode() string GetMessage() string GetError() string GetDescription() string } -type baseResult struct { +type apiResponseBase struct { StatusCode json.RawMessage `json:"statusCode,omitempty"` Message *string `json:"message,omitempty"` Error *string `json:"error,omitempty"` @@ -21,7 +21,7 @@ type baseResult struct { RequestId *string `json:"requestId,omitempty"` } -func (r *baseResult) GetStatusCode() string { +func (r *apiResponseBase) GetStatusCode() string { if r.StatusCode == nil { return "" } @@ -44,7 +44,7 @@ func (r *baseResult) GetStatusCode() string { } } -func (r *baseResult) GetMessage() string { +func (r *apiResponseBase) GetMessage() string { if r.Message == nil { return "" } @@ -52,7 +52,7 @@ func (r *baseResult) GetMessage() string { return *r.Message } -func (r *baseResult) GetError() string { +func (r *apiResponseBase) GetError() string { if r.Error == nil { return "" } @@ -60,7 +60,7 @@ func (r *baseResult) GetError() string { return *r.Error } -func (r *baseResult) GetDescription() string { +func (r *apiResponseBase) GetDescription() string { if r.Description == nil { return "" } @@ -68,7 +68,7 @@ func (r *baseResult) GetDescription() string { return *r.Description } -var _ baseResultInterface = (*baseResult)(nil) +var _ apiResponse = (*apiResponseBase)(nil) type CertificateRecord struct { ID string `json:"ID"` diff --git a/internal/pkg/sdk3rd/ctyun/icdn/api_create_cert.go b/internal/pkg/sdk3rd/ctyun/icdn/api_create_cert.go index 93c09087..0261bb43 100644 --- a/internal/pkg/sdk3rd/ctyun/icdn/api_create_cert.go +++ b/internal/pkg/sdk3rd/ctyun/icdn/api_create_cert.go @@ -12,7 +12,7 @@ type CreateCertRequest struct { } type CreateCertResponse struct { - baseResult + apiResponseBase ReturnObj *struct { Id int64 `json:"id"` diff --git a/internal/pkg/sdk3rd/ctyun/icdn/api_query_cert_detail.go b/internal/pkg/sdk3rd/ctyun/icdn/api_query_cert_detail.go index 2842d1f7..75beca46 100644 --- a/internal/pkg/sdk3rd/ctyun/icdn/api_query_cert_detail.go +++ b/internal/pkg/sdk3rd/ctyun/icdn/api_query_cert_detail.go @@ -13,7 +13,7 @@ type QueryCertDetailRequest struct { } type QueryCertDetailResponse struct { - baseResult + apiResponseBase ReturnObj *struct { Result *CertDetail `json:"result,omitempty"` diff --git a/internal/pkg/sdk3rd/ctyun/icdn/api_query_cert_list.go b/internal/pkg/sdk3rd/ctyun/icdn/api_query_cert_list.go index a96ab7b1..806a77fe 100644 --- a/internal/pkg/sdk3rd/ctyun/icdn/api_query_cert_list.go +++ b/internal/pkg/sdk3rd/ctyun/icdn/api_query_cert_list.go @@ -13,7 +13,7 @@ type QueryCertListRequest struct { } type QueryCertListResponse struct { - baseResult + apiResponseBase ReturnObj *struct { Results []*CertRecord `json:"result,omitempty"` diff --git a/internal/pkg/sdk3rd/ctyun/icdn/api_query_domain_detail.go b/internal/pkg/sdk3rd/ctyun/icdn/api_query_domain_detail.go index 2ecff27e..ace1bddb 100644 --- a/internal/pkg/sdk3rd/ctyun/icdn/api_query_domain_detail.go +++ b/internal/pkg/sdk3rd/ctyun/icdn/api_query_domain_detail.go @@ -12,7 +12,7 @@ type QueryDomainDetailRequest struct { } type QueryDomainDetailResponse struct { - baseResult + apiResponseBase ReturnObj *struct { Domain string `json:"domain"` diff --git a/internal/pkg/sdk3rd/ctyun/icdn/api_update_domain.go b/internal/pkg/sdk3rd/ctyun/icdn/api_update_domain.go index 70d3b73a..d3e421c4 100644 --- a/internal/pkg/sdk3rd/ctyun/icdn/api_update_domain.go +++ b/internal/pkg/sdk3rd/ctyun/icdn/api_update_domain.go @@ -12,7 +12,7 @@ type UpdateDomainRequest struct { } type UpdateDomainResponse struct { - baseResult + apiResponseBase } func (c *Client) UpdateDomain(req *UpdateDomainRequest) (*UpdateDomainResponse, error) { diff --git a/internal/pkg/sdk3rd/ctyun/icdn/client.go b/internal/pkg/sdk3rd/ctyun/icdn/client.go index 5f3e0084..f7bf4d96 100644 --- a/internal/pkg/sdk3rd/ctyun/icdn/client.go +++ b/internal/pkg/sdk3rd/ctyun/icdn/client.go @@ -32,18 +32,17 @@ func (c *Client) newRequest(method string, path string) (*resty.Request, error) return c.client.NewRequest(method, path) } -func (c *Client) doRequest(request *resty.Request) (*resty.Response, error) { - return c.client.DoRequest(request) +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + return c.client.DoRequest(req) } -func (c *Client) doRequestWithResult(request *resty.Request, result baseResultInterface) (*resty.Response, error) { - response, err := c.client.DoRequestWithResult(request, result) +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + resp, err := c.client.DoRequestWithResult(req, res) if err == nil { - statusCode := result.GetStatusCode() - if statusCode != "" && statusCode != "100000" { - return response, fmt.Errorf("sdkerr: api error, code='%s', message='%s', errorCode='%s', errorMessage='%s'", statusCode, result.GetMessage(), result.GetMessage(), result.GetErrorMessage()) + if tcode := res.GetStatusCode(); tcode != "" && tcode != "100000" { + return resp, fmt.Errorf("sdkerr: api error, code='%s', message='%s', errorCode='%s', errorMessage='%s'", tcode, res.GetMessage(), res.GetMessage(), res.GetErrorMessage()) } } - return response, err + return resp, err } diff --git a/internal/pkg/sdk3rd/ctyun/icdn/types.go b/internal/pkg/sdk3rd/ctyun/icdn/types.go index 2b2f3d95..0d1e8fb6 100644 --- a/internal/pkg/sdk3rd/ctyun/icdn/types.go +++ b/internal/pkg/sdk3rd/ctyun/icdn/types.go @@ -6,14 +6,14 @@ import ( "strconv" ) -type baseResultInterface interface { +type apiResponse interface { GetStatusCode() string GetMessage() string GetError() string GetErrorMessage() string } -type baseResult struct { +type apiResponseBase struct { StatusCode json.RawMessage `json:"statusCode,omitempty"` Message *string `json:"message,omitempty"` Error *string `json:"error,omitempty"` @@ -21,7 +21,7 @@ type baseResult struct { RequestId *string `json:"requestId,omitempty"` } -func (r *baseResult) GetStatusCode() string { +func (r *apiResponseBase) GetStatusCode() string { if r.StatusCode == nil { return "" } @@ -44,7 +44,7 @@ func (r *baseResult) GetStatusCode() string { } } -func (r *baseResult) GetMessage() string { +func (r *apiResponseBase) GetMessage() string { if r.Message == nil { return "" } @@ -52,7 +52,7 @@ func (r *baseResult) GetMessage() string { return *r.Message } -func (r *baseResult) GetError() string { +func (r *apiResponseBase) GetError() string { if r.Error == nil { return "" } @@ -60,7 +60,7 @@ func (r *baseResult) GetError() string { return *r.Error } -func (r *baseResult) GetErrorMessage() string { +func (r *apiResponseBase) GetErrorMessage() string { if r.ErrorMessage == nil { return "" } @@ -68,7 +68,7 @@ func (r *baseResult) GetErrorMessage() string { return *r.ErrorMessage } -var _ baseResultInterface = (*baseResult)(nil) +var _ apiResponse = (*apiResponseBase)(nil) type CertRecord struct { Id int64 `json:"id"` diff --git a/internal/pkg/sdk3rd/ctyun/lvdn/api_create_cert.go b/internal/pkg/sdk3rd/ctyun/lvdn/api_create_cert.go index c0188d3d..b10e4011 100644 --- a/internal/pkg/sdk3rd/ctyun/lvdn/api_create_cert.go +++ b/internal/pkg/sdk3rd/ctyun/lvdn/api_create_cert.go @@ -12,7 +12,7 @@ type CreateCertRequest struct { } type CreateCertResponse struct { - baseResult + apiResponseBase ReturnObj *struct { Id int64 `json:"id"` diff --git a/internal/pkg/sdk3rd/ctyun/lvdn/api_query_cert_detail.go b/internal/pkg/sdk3rd/ctyun/lvdn/api_query_cert_detail.go index cadcc6dc..f3427ad4 100644 --- a/internal/pkg/sdk3rd/ctyun/lvdn/api_query_cert_detail.go +++ b/internal/pkg/sdk3rd/ctyun/lvdn/api_query_cert_detail.go @@ -13,7 +13,7 @@ type QueryCertDetailRequest struct { } type QueryCertDetailResponse struct { - baseResult + apiResponseBase ReturnObj *struct { Result *CertDetail `json:"result,omitempty"` diff --git a/internal/pkg/sdk3rd/ctyun/lvdn/api_query_cert_list.go b/internal/pkg/sdk3rd/ctyun/lvdn/api_query_cert_list.go index d1a7b974..d7fb5ebd 100644 --- a/internal/pkg/sdk3rd/ctyun/lvdn/api_query_cert_list.go +++ b/internal/pkg/sdk3rd/ctyun/lvdn/api_query_cert_list.go @@ -13,7 +13,7 @@ type QueryCertListRequest struct { } type QueryCertListResponse struct { - baseResult + apiResponseBase ReturnObj *struct { Results []*CertRecord `json:"result,omitempty"` diff --git a/internal/pkg/sdk3rd/ctyun/lvdn/api_query_domain_detail.go b/internal/pkg/sdk3rd/ctyun/lvdn/api_query_domain_detail.go index 29e5f08f..fde83efb 100644 --- a/internal/pkg/sdk3rd/ctyun/lvdn/api_query_domain_detail.go +++ b/internal/pkg/sdk3rd/ctyun/lvdn/api_query_domain_detail.go @@ -11,7 +11,7 @@ type QueryDomainDetailRequest struct { } type QueryDomainDetailResponse struct { - baseResult + apiResponseBase ReturnObj *struct { Domain string `json:"domain"` diff --git a/internal/pkg/sdk3rd/ctyun/lvdn/api_update_domain.go b/internal/pkg/sdk3rd/ctyun/lvdn/api_update_domain.go index d5f90306..0a0f2ef2 100644 --- a/internal/pkg/sdk3rd/ctyun/lvdn/api_update_domain.go +++ b/internal/pkg/sdk3rd/ctyun/lvdn/api_update_domain.go @@ -13,7 +13,7 @@ type UpdateDomainRequest struct { } type UpdateDomainResponse struct { - baseResult + apiResponseBase } func (c *Client) UpdateDomain(req *UpdateDomainRequest) (*UpdateDomainResponse, error) { diff --git a/internal/pkg/sdk3rd/ctyun/lvdn/client.go b/internal/pkg/sdk3rd/ctyun/lvdn/client.go index 5542bad9..39c8b3b7 100644 --- a/internal/pkg/sdk3rd/ctyun/lvdn/client.go +++ b/internal/pkg/sdk3rd/ctyun/lvdn/client.go @@ -32,18 +32,17 @@ func (c *Client) newRequest(method string, path string) (*resty.Request, error) return c.client.NewRequest(method, path) } -func (c *Client) doRequest(request *resty.Request) (*resty.Response, error) { - return c.client.DoRequest(request) +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + return c.client.DoRequest(req) } -func (c *Client) doRequestWithResult(request *resty.Request, result baseResultInterface) (*resty.Response, error) { - response, err := c.client.DoRequestWithResult(request, result) +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + resp, err := c.client.DoRequestWithResult(req, res) if err == nil { - statusCode := result.GetStatusCode() - if statusCode != "" && statusCode != "100000" { - return response, fmt.Errorf("sdkerr: api error, code='%s', message='%s', errorCode='%s', errorMessage='%s'", statusCode, result.GetMessage(), result.GetMessage(), result.GetErrorMessage()) + if tcode := res.GetStatusCode(); tcode != "" && tcode != "100000" { + return resp, fmt.Errorf("sdkerr: api error, code='%s', message='%s', errorCode='%s', errorMessage='%s'", tcode, res.GetMessage(), res.GetMessage(), res.GetErrorMessage()) } } - return response, err + return resp, err } diff --git a/internal/pkg/sdk3rd/ctyun/lvdn/types.go b/internal/pkg/sdk3rd/ctyun/lvdn/types.go index 2ddc5369..838fc38f 100644 --- a/internal/pkg/sdk3rd/ctyun/lvdn/types.go +++ b/internal/pkg/sdk3rd/ctyun/lvdn/types.go @@ -6,14 +6,14 @@ import ( "strconv" ) -type baseResultInterface interface { +type apiResponse interface { GetStatusCode() string GetMessage() string GetError() string GetErrorMessage() string } -type baseResult struct { +type apiResponseBase struct { StatusCode json.RawMessage `json:"statusCode,omitempty"` Message *string `json:"message,omitempty"` Error *string `json:"error,omitempty"` @@ -21,7 +21,7 @@ type baseResult struct { RequestId *string `json:"requestId,omitempty"` } -func (r *baseResult) GetStatusCode() string { +func (r *apiResponseBase) GetStatusCode() string { if r.StatusCode == nil { return "" } @@ -44,7 +44,7 @@ func (r *baseResult) GetStatusCode() string { } } -func (r *baseResult) GetMessage() string { +func (r *apiResponseBase) GetMessage() string { if r.Message == nil { return "" } @@ -52,7 +52,7 @@ func (r *baseResult) GetMessage() string { return *r.Message } -func (r *baseResult) GetError() string { +func (r *apiResponseBase) GetError() string { if r.Error == nil { return "" } @@ -60,7 +60,7 @@ func (r *baseResult) GetError() string { return *r.Error } -func (r *baseResult) GetErrorMessage() string { +func (r *apiResponseBase) GetErrorMessage() string { if r.ErrorMessage == nil { return "" } @@ -68,7 +68,7 @@ func (r *baseResult) GetErrorMessage() string { return *r.ErrorMessage } -var _ baseResultInterface = (*baseResult)(nil) +var _ apiResponse = (*apiResponseBase)(nil) type CertRecord struct { Id int64 `json:"id"` diff --git a/internal/pkg/sdk3rd/ctyun/openapi/client.go b/internal/pkg/sdk3rd/ctyun/openapi/client.go index ad790dc5..62a733d0 100644 --- a/internal/pkg/sdk3rd/ctyun/openapi/client.go +++ b/internal/pkg/sdk3rd/ctyun/openapi/client.go @@ -28,10 +28,10 @@ func NewClient(endpoint, accessKeyId, secretAccessKey string) (*Client, error) { return nil, fmt.Errorf("sdkerr: invalid endpoint: %w", err) } if accessKeyId == "" { - return nil, fmt.Errorf("sdkerr: unset accessKey") + return nil, fmt.Errorf("sdkerr: unset accessKeyId") } if secretAccessKey == "" { - return nil, fmt.Errorf("sdkerr: unset secretKey") + return nil, fmt.Errorf("sdkerr: unset secretAccessKey") } client := resty.New(). @@ -102,9 +102,7 @@ func NewClient(endpoint, accessKeyId, secretAccessKey string) (*Client, error) { return nil }) - return &Client{ - client: client, - }, nil + return &Client{client}, nil } func (c *Client) SetTimeout(timeout time.Duration) *Client { @@ -126,15 +124,15 @@ func (c *Client) NewRequest(method string, path string) (*resty.Request, error) return req, nil } -func (c *Client) DoRequest(request *resty.Request) (*resty.Response, error) { - if request == nil { +func (c *Client) DoRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { return nil, fmt.Errorf("sdkerr: nil request") } // WARN: - // PLEASE DO NOT USE `req.SetResult` or `req.SetError` here. + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. - resp, err := request.Send() + resp, err := req.Send() if err != nil { return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) } else if resp.IsError() { @@ -144,24 +142,24 @@ func (c *Client) DoRequest(request *resty.Request) (*resty.Response, error) { return resp, nil } -func (c *Client) DoRequestWithResult(request *resty.Request, result any) (*resty.Response, error) { - if request == nil { +func (c *Client) DoRequestWithResult(req *resty.Request, res any) (*resty.Response, error) { + if req == nil { return nil, fmt.Errorf("sdkerr: nil request") } - response, err := c.DoRequest(request) + resp, err := c.DoRequest(req) if err != nil { - if response != nil { - json.Unmarshal(response.Body(), &result) + if resp != nil { + json.Unmarshal(resp.Body(), &res) } - return response, err + return resp, err } - if len(response.Body()) != 0 { - if err := json.Unmarshal(response.Body(), &result); err != nil { - return response, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) } } - return response, nil + return resp, nil } diff --git a/internal/pkg/sdk3rd/dcloud/unicloud/api.go b/internal/pkg/sdk3rd/dcloud/unicloud/api.go deleted file mode 100644 index 1cd90b15..00000000 --- a/internal/pkg/sdk3rd/dcloud/unicloud/api.go +++ /dev/null @@ -1,78 +0,0 @@ -package unicloud - -import ( - "fmt" - "net/http" - "regexp" - "time" -) - -func (c *Client) ensureServerlessJwtTokenExists() error { - c.serverlessJwtTokenMtx.Lock() - defer c.serverlessJwtTokenMtx.Unlock() - if c.serverlessJwtToken != "" && c.serverlessJwtTokenExp.After(time.Now()) { - return nil - } - - params := &loginParams{ - Password: c.password, - } - if regexp.MustCompile("^1\\d{10}$").MatchString(c.username) { - params.Mobile = c.username - } else if regexp.MustCompile("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$").MatchString(c.username) { - params.Email = c.username - } else { - params.Username = c.username - } - - resp := &loginResponse{} - if err := c.invokeServerlessWithResult( - uniIdentityEndpoint, uniIdentityClientSecret, uniIdentityAppId, uniIdentitySpaceId, - "uni-id-co", "login", "", params, nil, - resp); err != nil { - return err - } else if resp.Data == nil || resp.Data.NewToken == nil || resp.Data.NewToken.Token == "" { - return fmt.Errorf("unicloud api error: received empty token") - } - - c.serverlessJwtToken = resp.Data.NewToken.Token - c.serverlessJwtTokenExp = time.UnixMilli(resp.Data.NewToken.TokenExpired) - - return nil -} - -func (c *Client) ensureApiUserTokenExists() error { - if err := c.ensureServerlessJwtTokenExists(); err != nil { - return err - } - - c.apiUserTokenMtx.Lock() - defer c.apiUserTokenMtx.Unlock() - if c.apiUserToken != "" { - return nil - } - - resp := &getUserTokenResponse{} - if err := c.invokeServerlessWithResult( - uniConsoleEndpoint, uniConsoleClientSecret, uniConsoleAppId, uniConsoleSpaceId, - "uni-cloud-kernel", "", "user/getUserToken", nil, map[string]any{"isLogin": true}, - resp); err != nil { - return err - } else if resp.Data == nil || resp.Data.Data == nil || resp.Data.Data.Data == nil || resp.Data.Data.Data.Token == "" { - return fmt.Errorf("unicloud api error: received empty user token") - } - - c.apiUserToken = resp.Data.Data.Data.Token - - return nil -} - -func (c *Client) CreateDomainWithCert(req *CreateDomainWithCertRequest) (*CreateDomainWithCertResponse, error) { - if err := c.ensureApiUserTokenExists(); err != nil { - return nil, err - } - - resp := &CreateDomainWithCertResponse{} - err := c.sendRequestWithResult(http.MethodPost, "/host/create-domain-with-cert", req, resp) - return resp, err -} diff --git a/internal/pkg/sdk3rd/dcloud/unicloud/api_create_domain_with_cert.go b/internal/pkg/sdk3rd/dcloud/unicloud/api_create_domain_with_cert.go new file mode 100644 index 00000000..63ba6710 --- /dev/null +++ b/internal/pkg/sdk3rd/dcloud/unicloud/api_create_domain_with_cert.go @@ -0,0 +1,27 @@ +package unicloud + +import ( + "net/http" +) + +type CreateDomainWithCertRequest struct { + Provider string `json:"provider"` + SpaceId string `json:"spaceId"` + Domain string `json:"domain"` + Cert string `json:"cert"` + Key string `json:"key"` +} + +type CreateDomainWithCertResponse struct { + apiResponseBase +} + +func (c *Client) CreateDomainWithCert(req *CreateDomainWithCertRequest) (*CreateDomainWithCertResponse, error) { + if err := c.ensureApiUserTokenExists(); err != nil { + return nil, err + } + + resp := &CreateDomainWithCertResponse{} + err := c.sendRequestWithResult(http.MethodPost, "/host/create-domain-with-cert", req, resp) + return resp, err +} diff --git a/internal/pkg/sdk3rd/dcloud/unicloud/client.go b/internal/pkg/sdk3rd/dcloud/unicloud/client.go index 8db4a792..11e48619 100644 --- a/internal/pkg/sdk3rd/dcloud/unicloud/client.go +++ b/internal/pkg/sdk3rd/dcloud/unicloud/client.go @@ -7,6 +7,7 @@ import ( "encoding/json" "fmt" "net/http" + "regexp" "runtime" "sort" "strings" @@ -43,14 +44,26 @@ const ( uniConsoleSpaceId = "dc-6nfabcn6ada8d3dd" ) -func NewClient(username, password string) *Client { +func NewClient(username, password string) (*Client, error) { + if username == "" { + return nil, fmt.Errorf("sdkerr: unset username") + } + if password == "" { + return nil, fmt.Errorf("sdkerr: unset password") + } + client := &Client{ username: username, password: password, } - client.serverlessClient = resty.New() + client.serverlessClient = resty.New(). + SetHeader("Accept", "application/json"). + SetHeader("Content-Type", "application/json"). + SetHeader("User-Agent", "certimate") client.apiClient = resty.New(). SetBaseURL("https://unicloud-api.dcloud.net.cn/unicloud/api"). + SetHeader("Accept", "application/json"). + SetHeader("Content-Type", "application/json"). SetHeader("User-Agent", "certimate"). SetPreRequestHook(func(c *resty.Client, req *http.Request) error { if client.apiUserToken != "" { @@ -60,37 +73,14 @@ func NewClient(username, password string) *Client { return nil }) - return client + return client, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { +func (c *Client) SetTimeout(timeout time.Duration) *Client { c.serverlessClient.SetTimeout(timeout) return c } -func (c *Client) generateSignature(params map[string]any, secret string) string { - keys := make([]string, 0, len(params)) - for k := range params { - keys = append(keys, k) - } - sort.Strings(keys) - - canonicalStr := "" - for i, k := range keys { - if i > 0 { - canonicalStr += "&" - } - canonicalStr += k + "=" + fmt.Sprintf("%v", params[k]) - } - - mac := hmac.New(md5.New, []byte(secret)) - mac.Write([]byte(canonicalStr)) - sign := mac.Sum(nil) - signHex := hex.EncodeToString(sign) - - return signHex -} - func (c *Client) buildServerlessClientInfo(appId string) (_clientInfo map[string]any, _err error) { return map[string]any{ "PLATFORM": "web", @@ -171,7 +161,7 @@ func (c *Client) invokeServerless(endpoint, clientSecret, appId, spaceId, target clientInfo, _ := c.buildServerlessClientInfo(appId) clientInfoJsonb, _ := json.Marshal(clientInfo) - sign := c.generateSignature(payload, clientSecret) + sign := generateSignature(payload, clientSecret) req := c.serverlessClient.R(). SetHeader("Content-Type", "application/json"). @@ -191,7 +181,7 @@ func (c *Client) invokeServerless(endpoint, clientSecret, appId, spaceId, target return resp, nil } -func (c *Client) invokeServerlessWithResult(endpoint, clientSecret, appId, spaceId, target, method, action string, params, data interface{}, result BaseResponse) error { +func (c *Client) invokeServerlessWithResult(endpoint, clientSecret, appId, spaceId, target, method, action string, params, data interface{}, result apiResponse) error { resp, err := c.invokeServerless(endpoint, clientSecret, appId, spaceId, target, method, action, params, data) if err != nil { if resp != nil { @@ -239,7 +229,7 @@ func (c *Client) sendRequest(method string, path string, params interface{}) (*r return resp, nil } -func (c *Client) sendRequestWithResult(method string, path string, params interface{}, result BaseResponse) error { +func (c *Client) sendRequestWithResult(method string, path string, params interface{}, result apiResponse) error { resp, err := c.sendRequest(method, path, params) if err != nil { if resp != nil { @@ -256,3 +246,113 @@ func (c *Client) sendRequestWithResult(method string, path string, params interf return nil } + +func (c *Client) ensureServerlessJwtTokenExists() error { + c.serverlessJwtTokenMtx.Lock() + defer c.serverlessJwtTokenMtx.Unlock() + if c.serverlessJwtToken != "" && c.serverlessJwtTokenExp.After(time.Now()) { + return nil + } + + params := map[string]string{ + "password": "password", + } + if regexp.MustCompile("^1\\d{10}$").MatchString(c.username) { + params["mobile"] = c.username + } else if regexp.MustCompile("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$").MatchString(c.username) { + params["email"] = c.username + } else { + params["username"] = c.username + } + + type loginResponse struct { + apiResponseBase + Data *struct { + Code int32 `json:"errCode"` + UID string `json:"uid"` + NewToken *struct { + Token string `json:"token"` + TokenExpired int64 `json:"tokenExpired"` + } `json:"newToken,omitempty"` + } `json:"data,omitempty"` + } + + resp := &loginResponse{} + if err := c.invokeServerlessWithResult( + uniIdentityEndpoint, uniIdentityClientSecret, uniIdentityAppId, uniIdentitySpaceId, + "uni-id-co", "login", "", params, nil, + resp); err != nil { + return err + } else if resp.Data == nil || resp.Data.NewToken == nil || resp.Data.NewToken.Token == "" { + return fmt.Errorf("unicloud api error: received empty token") + } + + c.serverlessJwtToken = resp.Data.NewToken.Token + c.serverlessJwtTokenExp = time.UnixMilli(resp.Data.NewToken.TokenExpired) + + return nil +} + +func (c *Client) ensureApiUserTokenExists() error { + if err := c.ensureServerlessJwtTokenExists(); err != nil { + return err + } + + c.apiUserTokenMtx.Lock() + defer c.apiUserTokenMtx.Unlock() + if c.apiUserToken != "" { + return nil + } + + type getUserTokenResponse struct { + apiResponseBase + Data *struct { + Code int32 `json:"code"` + Data *struct { + Result int32 `json:"ret"` + Description string `json:"desc"` + Data *struct { + Email string `json:"email"` + Token string `json:"token"` + } `json:"data,omitempty"` + } `json:"data,omitempty"` + } `json:"data,omitempty"` + } + + resp := &getUserTokenResponse{} + if err := c.invokeServerlessWithResult( + uniConsoleEndpoint, uniConsoleClientSecret, uniConsoleAppId, uniConsoleSpaceId, + "uni-cloud-kernel", "", "user/getUserToken", nil, map[string]any{"isLogin": true}, + resp); err != nil { + return err + } else if resp.Data == nil || resp.Data.Data == nil || resp.Data.Data.Data == nil || resp.Data.Data.Data.Token == "" { + return fmt.Errorf("unicloud api error: received empty user token") + } + + c.apiUserToken = resp.Data.Data.Data.Token + + return nil +} + +func generateSignature(params map[string]any, secret string) string { + keys := make([]string, 0, len(params)) + for k := range params { + keys = append(keys, k) + } + sort.Strings(keys) + + canonicalStr := "" + for i, k := range keys { + if i > 0 { + canonicalStr += "&" + } + canonicalStr += k + "=" + fmt.Sprintf("%v", params[k]) + } + + mac := hmac.New(md5.New, []byte(secret)) + mac.Write([]byte(canonicalStr)) + sign := mac.Sum(nil) + signHex := hex.EncodeToString(sign) + + return signHex +} diff --git a/internal/pkg/sdk3rd/dcloud/unicloud/models.go b/internal/pkg/sdk3rd/dcloud/unicloud/models.go deleted file mode 100644 index 05b02db6..00000000 --- a/internal/pkg/sdk3rd/dcloud/unicloud/models.go +++ /dev/null @@ -1,103 +0,0 @@ -package unicloud - -type BaseResponse interface { - GetSuccess() bool - GetErrorCode() string - GetErrorMessage() string - - GetReturnCode() int32 - GetReturnDesc() string -} - -type baseResponse struct { - Success *bool `json:"success,omitempty"` - Header *map[string]string `json:"header,omitempty"` - Error *struct { - Code string `json:"code"` - Message string `json:"message"` - } `json:"error,omitempty"` - - ReturnCode *int32 `json:"ret,omitempty"` - ReturnDesc *string `json:"desc,omitempty"` -} - -func (r *baseResponse) GetReturnCode() int32 { - if r.ReturnCode != nil { - return *r.ReturnCode - } - return 0 -} - -func (r *baseResponse) GetReturnDesc() string { - if r.ReturnDesc != nil { - return *r.ReturnDesc - } - return "" -} - -func (r *baseResponse) GetSuccess() bool { - if r.Success != nil { - return *r.Success - } - return false -} - -func (r *baseResponse) GetErrorCode() string { - if r.Error != nil { - return r.Error.Code - } - return "" -} - -func (r *baseResponse) GetErrorMessage() string { - if r.Error != nil { - return r.Error.Message - } - return "" -} - -type loginParams struct { - Email string `json:"email,omitempty"` - Mobile string `json:"mobile,omitempty"` - Username string `json:"username,omitempty"` - Password string `json:"password"` -} - -type loginResponse struct { - baseResponse - Data *struct { - Code int32 `json:"errCode"` - UID string `json:"uid"` - NewToken *struct { - Token string `json:"token"` - TokenExpired int64 `json:"tokenExpired"` - } `json:"newToken,omitempty"` - } `json:"data,omitempty"` -} - -type getUserTokenResponse struct { - baseResponse - Data *struct { - Code int32 `json:"code"` - Data *struct { - Result int32 `json:"ret"` - Description string `json:"desc"` - Data *struct { - Email string `json:"email"` - Token string `json:"token"` - } `json:"data,omitempty"` - } `json:"data,omitempty"` - } `json:"data,omitempty"` -} - -type CreateDomainWithCertRequest struct { - Provider string `json:"provider"` - SpaceId string `json:"spaceId"` - Domain string `json:"domain"` - Cert string `json:"cert"` - Key string `json:"key"` -} - -type CreateDomainWithCertResponse struct { - baseResponse -} diff --git a/internal/pkg/sdk3rd/dcloud/unicloud/types.go b/internal/pkg/sdk3rd/dcloud/unicloud/types.go new file mode 100644 index 00000000..7fb72267 --- /dev/null +++ b/internal/pkg/sdk3rd/dcloud/unicloud/types.go @@ -0,0 +1,64 @@ +package unicloud + +type apiResponse interface { + GetSuccess() bool + GetErrorCode() string + GetErrorMessage() string + + GetReturnCode() int32 + GetReturnDesc() string +} + +type apiResponseBase struct { + Success *bool `json:"success,omitempty"` + Header *map[string]string `json:"header,omitempty"` + Error *struct { + Code string `json:"code"` + Message string `json:"message"` + } `json:"error,omitempty"` + + ReturnCode *int32 `json:"ret,omitempty"` + ReturnDesc *string `json:"desc,omitempty"` +} + +func (r *apiResponseBase) GetReturnCode() int32 { + if r.ReturnCode == nil { + return 0 + } + + return *r.ReturnCode +} + +func (r *apiResponseBase) GetReturnDesc() string { + if r.ReturnDesc == nil { + return "" + } + + return *r.ReturnDesc +} + +func (r *apiResponseBase) GetSuccess() bool { + if r.Success == nil { + return false + } + + return *r.Success +} + +func (r *apiResponseBase) GetErrorCode() string { + if r.Error == nil { + return "" + } + + return r.Error.Code +} + +func (r *apiResponseBase) GetErrorMessage() string { + if r.Error == nil { + return "" + } + + return r.Error.Message +} + +var _ apiResponse = (*apiResponseBase)(nil) diff --git a/internal/pkg/sdk3rd/dnsla/api.go b/internal/pkg/sdk3rd/dnsla/api.go deleted file mode 100644 index 6f999ce7..00000000 --- a/internal/pkg/sdk3rd/dnsla/api.go +++ /dev/null @@ -1,41 +0,0 @@ -package dnsla - -import ( - "fmt" - "net/http" - "net/url" -) - -func (c *Client) ListDomains(req *ListDomainsRequest) (*ListDomainsResponse, error) { - resp := &ListDomainsResponse{} - err := c.sendRequestWithResult(http.MethodGet, "/domainList", req, resp) - return resp, err -} - -func (c *Client) ListRecords(req *ListRecordsRequest) (*ListRecordsResponse, error) { - resp := &ListRecordsResponse{} - err := c.sendRequestWithResult(http.MethodGet, "/recordList", req, resp) - return resp, err -} - -func (c *Client) CreateRecord(req *CreateRecordRequest) (*CreateRecordResponse, error) { - resp := &CreateRecordResponse{} - err := c.sendRequestWithResult(http.MethodPost, "/record", req, resp) - return resp, err -} - -func (c *Client) UpdateRecord(req *UpdateRecordRequest) (*UpdateRecordResponse, error) { - resp := &UpdateRecordResponse{} - err := c.sendRequestWithResult(http.MethodPut, "/record", req, resp) - return resp, err -} - -func (c *Client) DeleteRecord(req *DeleteRecordRequest) (*DeleteRecordResponse, error) { - if req.Id == "" { - return nil, fmt.Errorf("dnsla api error: invalid parameter: Id") - } - - resp := &DeleteRecordResponse{} - err := c.sendRequestWithResult(http.MethodDelete, fmt.Sprintf("/record?id=%s", url.QueryEscape(req.Id)), req, resp) - return resp, err -} diff --git a/internal/pkg/sdk3rd/dnsla/api_create_record.go b/internal/pkg/sdk3rd/dnsla/api_create_record.go new file mode 100644 index 00000000..25d7f0d9 --- /dev/null +++ b/internal/pkg/sdk3rd/dnsla/api_create_record.go @@ -0,0 +1,46 @@ +package dnsla + +import ( + "context" + "net/http" +) + +type CreateRecordRequest struct { + DomainId string `json:"domainId"` + GroupId *string `json:"groupId,omitempty"` + LineId *string `json:"lineId,omitempty"` + Type int32 `json:"type"` + Host string `json:"host"` + Data string `json:"data"` + Ttl int32 `json:"ttl"` + Weight *int32 `json:"weight,omitempty"` + Preference *int32 `json:"preference,omitempty"` +} + +type CreateRecordResponse struct { + apiResponseBase + Data *struct { + Id string `json:"id"` + } `json:"data,omitempty"` +} + +func (c *Client) CreateRecord(req *CreateRecordRequest) (*CreateRecordResponse, error) { + return c.CreateRecordWithContext(context.Background(), req) +} + +func (c *Client) CreateRecordWithContext(ctx context.Context, req *CreateRecordRequest) (*CreateRecordResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/record") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &CreateRecordResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/dnsla/api_delete_record.go b/internal/pkg/sdk3rd/dnsla/api_delete_record.go new file mode 100644 index 00000000..97dcb5ff --- /dev/null +++ b/internal/pkg/sdk3rd/dnsla/api_delete_record.go @@ -0,0 +1,36 @@ +package dnsla + +import ( + "context" + "fmt" + "net/http" +) + +type DeleteRecordResponse struct { + apiResponseBase +} + +func (c *Client) DeleteRecord(recordId string) (*DeleteRecordResponse, error) { + return c.DeleteRecordWithContext(context.Background(), recordId) +} + +func (c *Client) DeleteRecordWithContext(ctx context.Context, recordId string) (*DeleteRecordResponse, error) { + if recordId == "" { + return nil, fmt.Errorf("sdkerr: unset recordId") + } + + httpreq, err := c.newRequest(http.MethodDelete, "/record") + if err != nil { + return nil, err + } else { + httpreq.SetQueryParam("id", recordId) + httpreq.SetContext(ctx) + } + + result := &DeleteRecordResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/dnsla/api_list_domains.go b/internal/pkg/sdk3rd/dnsla/api_list_domains.go new file mode 100644 index 00000000..d7972e98 --- /dev/null +++ b/internal/pkg/sdk3rd/dnsla/api_list_domains.go @@ -0,0 +1,51 @@ +package dnsla + +import ( + "context" + "net/http" + "strconv" +) + +type ListDomainsRequest struct { + GroupId *string `json:"groupId,omitempty"` + PageIndex *int32 `json:"pageIndex,omitempty"` + PageSize *int32 `json:"pageSize,omitempty"` +} + +type ListDomainsResponse struct { + apiResponseBase + Data *struct { + Total int32 `json:"total"` + Results []*DomainRecord `json:"results"` + } `json:"data,omitempty"` +} + +func (c *Client) ListDomains(req *ListDomainsRequest) (*ListDomainsResponse, error) { + return c.ListDomainsWithContext(context.Background(), req) +} + +func (c *Client) ListDomainsWithContext(ctx context.Context, req *ListDomainsRequest) (*ListDomainsResponse, error) { + httpreq, err := c.newRequest(http.MethodGet, "/domainList") + if err != nil { + return nil, err + } else { + if req.GroupId != nil { + httpreq.SetQueryParam("groupId", *req.GroupId) + } + if req.PageIndex != nil { + httpreq.SetQueryParam("pageIndex", strconv.Itoa(int(*req.PageIndex))) + } + if req.PageSize != nil { + httpreq.SetQueryParam("pageSize", strconv.Itoa(int(*req.PageSize))) + } + + httpreq.SetContext(ctx) + } + + result := &ListDomainsResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/dnsla/api_list_records.go b/internal/pkg/sdk3rd/dnsla/api_list_records.go new file mode 100644 index 00000000..4e77cc2f --- /dev/null +++ b/internal/pkg/sdk3rd/dnsla/api_list_records.go @@ -0,0 +1,71 @@ +package dnsla + +import ( + "context" + "net/http" + "strconv" +) + +type ListRecordsRequest struct { + DomainId *string `json:"domainId,omitempty"` + GroupId *string `json:"groupId,omitempty"` + LineId *string `json:"lineId,omitempty"` + Type *int32 `json:"type,omitempty"` + Host *string `json:"host,omitempty"` + Data *string `json:"data,omitempty"` + PageIndex *int32 `json:"pageIndex,omitempty"` + PageSize *int32 `json:"pageSize,omitempty"` +} + +type ListRecordsResponse struct { + apiResponseBase + Data *struct { + Total int32 `json:"total"` + Results []*DnsRecord `json:"results"` + } `json:"data,omitempty"` +} + +func (c *Client) ListRecords(req *ListRecordsRequest) (*ListRecordsResponse, error) { + return c.ListRecordsWithContext(context.Background(), req) +} + +func (c *Client) ListRecordsWithContext(ctx context.Context, req *ListRecordsRequest) (*ListRecordsResponse, error) { + httpreq, err := c.newRequest(http.MethodGet, "/recordList") + if err != nil { + return nil, err + } else { + if req.DomainId != nil { + httpreq.SetQueryParam("domainId", *req.DomainId) + } + if req.GroupId != nil { + httpreq.SetQueryParam("groupId", *req.GroupId) + } + if req.LineId != nil { + httpreq.SetQueryParam("lineId", *req.LineId) + } + if req.Type != nil { + httpreq.SetQueryParam("type", strconv.Itoa(int(*req.Type))) + } + if req.Host != nil { + httpreq.SetQueryParam("host", *req.Host) + } + if req.Data != nil { + httpreq.SetQueryParam("data", *req.Data) + } + if req.PageIndex != nil { + httpreq.SetQueryParam("pageIndex", strconv.Itoa(int(*req.PageIndex))) + } + if req.PageSize != nil { + httpreq.SetQueryParam("pageSize", strconv.Itoa(int(*req.PageSize))) + } + + httpreq.SetContext(ctx) + } + + result := &ListRecordsResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/dnsla/api_update_record.go b/internal/pkg/sdk3rd/dnsla/api_update_record.go new file mode 100644 index 00000000..2ab147ce --- /dev/null +++ b/internal/pkg/sdk3rd/dnsla/api_update_record.go @@ -0,0 +1,43 @@ +package dnsla + +import ( + "context" + "net/http" +) + +type UpdateRecordRequest struct { + Id string `json:"id"` + GroupId *string `json:"groupId,omitempty"` + LineId *string `json:"lineId,omitempty"` + Type *int32 `json:"type,omitempty"` + Host *string `json:"host,omitempty"` + Data *string `json:"data,omitempty"` + Ttl *int32 `json:"ttl,omitempty"` + Weight *int32 `json:"weight,omitempty"` + Preference *int32 `json:"preference,omitempty"` +} + +type UpdateRecordResponse struct { + apiResponseBase +} + +func (c *Client) UpdateRecord(req *UpdateRecordRequest) (*UpdateRecordResponse, error) { + return c.UpdateRecordWithContext(context.Background(), req) +} + +func (c *Client) UpdateRecordWithContext(ctx context.Context, req *UpdateRecordRequest) (*UpdateRecordResponse, error) { + httpreq, err := c.newRequest(http.MethodPut, "/record") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &UpdateRecordResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/dnsla/client.go b/internal/pkg/sdk3rd/dnsla/client.go index accd36d9..6add34a4 100644 --- a/internal/pkg/sdk3rd/dnsla/client.go +++ b/internal/pkg/sdk3rd/dnsla/client.go @@ -3,8 +3,6 @@ package dnsla import ( "encoding/json" "fmt" - "net/http" - "strings" "time" "github.com/go-resty/resty/v2" @@ -14,66 +12,83 @@ type Client struct { client *resty.Client } -func NewClient(apiId, apiSecret string) *Client { +func NewClient(apiId, apiSecret string) (*Client, error) { + if apiId == "" { + return nil, fmt.Errorf("sdkerr: unset apiId") + } + if apiSecret == "" { + return nil, fmt.Errorf("sdkerr: unset apiSecret") + } + client := resty.New(). SetBaseURL("https://api.dns.la/api"). SetBasicAuth(apiId, apiSecret). + SetHeader("Accept", "application/json"). + SetHeader("Content-Type", "application/json"). SetHeader("User-Agent", "certimate") - return &Client{ - client: client, - } + return &Client{client}, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { +func (c *Client) SetTimeout(timeout time.Duration) *Client { c.client.SetTimeout(timeout) return c } -func (c *Client) sendRequest(method string, path string, params interface{}) (*resty.Response, error) { - req := c.client.R() - if strings.EqualFold(method, http.MethodGet) { - qs := make(map[string]string) - if params != nil { - temp := make(map[string]any) - jsonb, _ := json.Marshal(params) - json.Unmarshal(jsonb, &temp) - for k, v := range temp { - if v != nil { - qs[k] = fmt.Sprintf("%v", v) - } - } - } - - req = req.SetQueryParams(qs) - } else { - req = req.SetHeader("Content-Type", "application/json").SetBody(params) +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") } - resp, err := req.Execute(method, path) + req := c.client.R() + req.Method = method + req.URL = path + return req, nil +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + // WARN: + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. + + resp, err := req.Send() if err != nil { - return resp, fmt.Errorf("dnsla api error: failed to send request: %w", err) + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) } else if resp.IsError() { - return resp, fmt.Errorf("dnsla api error: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) } return resp, nil } -func (c *Client) sendRequestWithResult(method string, path string, params interface{}, result BaseResponse) error { - resp, err := c.sendRequest(method, path, params) +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + resp, err := c.doRequest(req) if err != nil { if resp != nil { - json.Unmarshal(resp.Body(), &result) + json.Unmarshal(resp.Body(), &res) } - return err + return resp, err } - if err := json.Unmarshal(resp.Body(), &result); err != nil { - return fmt.Errorf("dnsla api error: failed to unmarshal response: %w", err) - } else if errcode := result.GetCode(); errcode/100 != 2 { - return fmt.Errorf("dnsla api error: code='%d', message='%s'", errcode, result.GetMessage()) + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) + } else { + if tcode := res.GetCode(); tcode/100 != 2 { + return resp, fmt.Errorf("sdkerr: code='%d', message='%s'", tcode, res.GetMessage()) + } + } } - return nil + return resp, nil } diff --git a/internal/pkg/sdk3rd/dnsla/models.go b/internal/pkg/sdk3rd/dnsla/models.go deleted file mode 100644 index 38fd623b..00000000 --- a/internal/pkg/sdk3rd/dnsla/models.go +++ /dev/null @@ -1,131 +0,0 @@ -package dnsla - -type BaseResponse interface { - GetCode() int32 - GetMessage() string -} - -type baseResponse struct { - Code *int32 `json:"code,omitempty"` - Message *string `json:"message,omitempty"` -} - -func (r *baseResponse) GetCode() int32 { - if r.Code != nil { - return *r.Code - } - return 0 -} - -func (r *baseResponse) GetMessage() string { - if r.Message != nil { - return *r.Message - } - return "" -} - -type DomainInfo struct { - Id string `json:"id"` - GroupId string `json:"groupId"` - GroupName string `json:"groupName"` - Domain string `json:"domain"` - DisplayDomain string `json:"displayDomain"` - CreatedAt int64 `json:"createdAt"` - UpdatedAt int64 `json:"updatedAt"` -} - -type RecordInfo struct { - Id string `json:"id"` - DomainId string `json:"domainId"` - GroupId string `json:"groupId"` - GroupName string `json:"groupName"` - LineId string `json:"lineId"` - LineCode string `json:"lineCode"` - LineName string `json:"lineName"` - Type int32 `json:"type"` - Host string `json:"host"` - DisplayHost string `json:"displayHost"` - Data string `json:"data"` - DisplayData string `json:"displayData"` - Ttl int32 `json:"ttl"` - Weight int32 `json:"weight"` - Preference int32 `json:"preference"` - CreatedAt int64 `json:"createdAt"` - UpdatedAt int64 `json:"updatedAt"` -} - -type ListDomainsRequest struct { - PageIndex int32 `json:"pageIndex"` - PageSize int32 `json:"pageSize"` - GroupId *string `json:"groupId,omitempty"` -} - -type ListDomainsResponse struct { - baseResponse - Data *struct { - Total int32 `json:"total"` - Results []*DomainInfo `json:"results"` - } `json:"data,omitempty"` -} - -type ListRecordsRequest struct { - PageIndex int32 `json:"pageIndex"` - PageSize int32 `json:"pageSize"` - DomainId string `json:"domainId"` - GroupId *string `json:"groupId,omitempty"` - LineId *string `json:"lineId,omitempty"` - Type *int32 `json:"type,omitempty"` - Host *string `json:"host,omitempty"` - Data *string `json:"data,omitempty"` -} - -type ListRecordsResponse struct { - baseResponse - Data *struct { - Total int32 `json:"total"` - Results []*RecordInfo `json:"results"` - } `json:"data,omitempty"` -} - -type CreateRecordRequest struct { - DomainId string `json:"domainId"` - GroupId *string `json:"groupId,omitempty"` - LineId *string `json:"lineId,omitempty"` - Type int32 `json:"type"` - Host string `json:"host"` - Data string `json:"data"` - Ttl int32 `json:"ttl"` - Weight *int32 `json:"weight,omitempty"` - Preference *int32 `json:"preference,omitempty"` -} - -type CreateRecordResponse struct { - baseResponse - Data *struct { - Id string `json:"id"` - } `json:"data,omitempty"` -} - -type UpdateRecordRequest struct { - Id string `json:"id"` - GroupId *string `json:"groupId,omitempty"` - LineId *string `json:"lineId,omitempty"` - Type *int32 `json:"type,omitempty"` - Host *string `json:"host,omitempty"` - Data *string `json:"data,omitempty"` - Ttl *int32 `json:"ttl,omitempty"` - Weight *int32 `json:"weight,omitempty"` - Preference *int32 `json:"preference,omitempty"` -} - -type UpdateRecordResponse struct { - baseResponse -} - -type DeleteRecordRequest struct { - Id string `json:"-"` -} - -type DeleteRecordResponse struct { - baseResponse -} diff --git a/internal/pkg/sdk3rd/dnsla/types.go b/internal/pkg/sdk3rd/dnsla/types.go new file mode 100644 index 00000000..acb3767c --- /dev/null +++ b/internal/pkg/sdk3rd/dnsla/types.go @@ -0,0 +1,59 @@ +package dnsla + +type apiResponse interface { + GetCode() int32 + GetMessage() string +} + +type apiResponseBase struct { + Code *int32 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` +} + +func (r *apiResponseBase) GetCode() int32 { + if r.Code == nil { + return 0 + } + + return *r.Code +} + +func (r *apiResponseBase) GetMessage() string { + if r.Message == nil { + return "" + } + + return *r.Message +} + +var _ apiResponse = (*apiResponseBase)(nil) + +type DomainRecord struct { + Id string `json:"id"` + GroupId string `json:"groupId"` + GroupName string `json:"groupName"` + Domain string `json:"domain"` + DisplayDomain string `json:"displayDomain"` + CreatedAt int64 `json:"createdAt"` + UpdatedAt int64 `json:"updatedAt"` +} + +type DnsRecord struct { + Id string `json:"id"` + DomainId string `json:"domainId"` + GroupId string `json:"groupId"` + GroupName string `json:"groupName"` + LineId string `json:"lineId"` + LineCode string `json:"lineCode"` + LineName string `json:"lineName"` + Type int32 `json:"type"` + Host string `json:"host"` + DisplayHost string `json:"displayHost"` + Data string `json:"data"` + DisplayData string `json:"displayData"` + Ttl int32 `json:"ttl"` + Weight int32 `json:"weight"` + Preference int32 `json:"preference"` + CreatedAt int64 `json:"createdAt"` + UpdatedAt int64 `json:"updatedAt"` +} diff --git a/internal/pkg/sdk3rd/dogecloud/api_bind_cdn_cert.go b/internal/pkg/sdk3rd/dogecloud/api_bind_cdn_cert.go new file mode 100644 index 00000000..59a0c3bf --- /dev/null +++ b/internal/pkg/sdk3rd/dogecloud/api_bind_cdn_cert.go @@ -0,0 +1,36 @@ +package dogecloud + +import ( + "context" + "net/http" +) + +type BindCdnCertRequest struct { + CertId int64 `json:"id"` + Domain string `json:"domain"` +} + +type BindCdnCertResponse struct { + apiResponseBase +} + +func (c *Client) BindCdnCert(req *BindCdnCertRequest) (*BindCdnCertResponse, error) { + return c.BindCdnCertWithContext(context.Background(), req) +} + +func (c *Client) BindCdnCertWithContext(ctx context.Context, req *BindCdnCertRequest) (*BindCdnCertResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/cdn/cert/bind.json") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &BindCdnCertResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/dogecloud/api_upload_cdn_cert.go b/internal/pkg/sdk3rd/dogecloud/api_upload_cdn_cert.go new file mode 100644 index 00000000..43f70fb3 --- /dev/null +++ b/internal/pkg/sdk3rd/dogecloud/api_upload_cdn_cert.go @@ -0,0 +1,41 @@ +package dogecloud + +import ( + "context" + "net/http" +) + +type UploadCdnCertRequest struct { + Note string `json:"note"` + Certificate string `json:"cert"` + PrivateKey string `json:"private"` +} + +type UploadCdnCertResponse struct { + apiResponseBase + + Data *struct { + Id int64 `json:"id"` + } `json:"data,omitempty"` +} + +func (c *Client) UploadCdnCert(req *UploadCdnCertRequest) (*UploadCdnCertResponse, error) { + return c.UploadCdnCertWithContext(context.Background(), req) +} + +func (c *Client) UploadCdnCertWithContext(ctx context.Context, req *UploadCdnCertRequest) (*UploadCdnCertResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/cdn/cert/upload.json") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &UploadCdnCertResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/dogecloud/client.go b/internal/pkg/sdk3rd/dogecloud/client.go index 75342907..f2088b00 100644 --- a/internal/pkg/sdk3rd/dogecloud/client.go +++ b/internal/pkg/sdk3rd/dogecloud/client.go @@ -8,176 +8,124 @@ import ( "fmt" "io" "net/http" - "net/url" - "strings" + "time" + + "github.com/go-resty/resty/v2" ) -const dogeHost = "https://api.dogecloud.com" - type Client struct { - accessKey string - secretKey string + client *resty.Client } -func NewClient(accessKey, secretKey string) *Client { - return &Client{accessKey: accessKey, secretKey: secretKey} +func NewClient(accessKey, secretKey string) (*Client, error) { + if accessKey == "" { + return nil, fmt.Errorf("sdkerr: unset accessKey") + } + if secretKey == "" { + return nil, fmt.Errorf("sdkerr: unset secretKey") + } + + client := resty.New(). + SetBaseURL("https://api.dogecloud.com"). + SetHeader("Accept", "application/json"). + SetHeader("Content-Type", "application/json"). + SetHeader("User-Agent", "certimate"). + SetPreRequestHook(func(ctx *resty.Client, req *http.Request) error { + requestUrl := req.URL.Path + requestQuery := req.URL.Query().Encode() + if requestQuery != "" { + requestUrl += "?" + requestQuery + } + + payload := "" + if req.Body != nil { + reader, err := req.GetBody() + if err != nil { + return err + } + + defer reader.Close() + + payloadb, err := io.ReadAll(reader) + if err != nil { + return err + } + + payload = string(payloadb) + } + + stringToSign := fmt.Sprintf("%s\n%s", requestUrl, payload) + mac := hmac.New(sha1.New, []byte(secretKey)) + mac.Write([]byte(stringToSign)) + sign := hex.EncodeToString(mac.Sum(nil)) + + req.Header.Set("Authorization", fmt.Sprintf("TOKEN %s:%s", accessKey, sign)) + + return nil + }) + + return &Client{client}, nil } -func (c *Client) UploadCdnCert(note, cert, private string) (*UploadCdnCertResponse, error) { - req := &UploadCdnCertRequest{ - Note: note, - Certificate: cert, - PrivateKey: private, +func (c *Client) SetTimeout(timeout time.Duration) *Client { + c.client.SetTimeout(timeout) + return c +} + +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") } - reqBts, err := json.Marshal(req) - if err != nil { - return nil, err + req := c.client.R() + req.Method = method + req.URL = path + return req, nil +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") } - reqMap := make(map[string]interface{}) - err = json.Unmarshal(reqBts, &reqMap) - if err != nil { - return nil, err - } + // WARN: + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. - respBts, err := c.sendReq(http.MethodPost, "cdn/cert/upload.json", reqMap, true) + resp, err := req.Send() if err != nil { - return nil, err - } - - resp := &UploadCdnCertResponse{} - err = json.Unmarshal(respBts, resp) - if err != nil { - return nil, err - } - if resp.Code != nil && *resp.Code != 0 && *resp.Code != 200 { - return nil, fmt.Errorf("dogecloud api error, code: %d, msg: %s", *resp.Code, *resp.Message) + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) + } else if resp.IsError() { + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) } return resp, nil } -func (c *Client) BindCdnCertWithDomain(certId int64, domain string) (*BindCdnCertResponse, error) { - req := &BindCdnCertRequest{ - CertId: certId, - Domain: &domain, +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") } - reqBts, err := json.Marshal(req) + resp, err := c.doRequest(req) if err != nil { - return nil, err - } - - reqMap := make(map[string]interface{}) - err = json.Unmarshal(reqBts, &reqMap) - if err != nil { - return nil, err - } - - respBts, err := c.sendReq(http.MethodPost, "cdn/cert/bind.json", reqMap, true) - if err != nil { - return nil, err - } - - resp := &BindCdnCertResponse{} - err = json.Unmarshal(respBts, resp) - if err != nil { - return nil, err - } - if resp.Code != nil && *resp.Code != 0 && *resp.Code != 200 { - return nil, fmt.Errorf("dogecloud api error, code: %d, msg: %s", *resp.Code, *resp.Message) - } - - return resp, nil -} - -func (c *Client) BindCdnCertWithDomainId(certId int64, domainId int64) (*BindCdnCertResponse, error) { - req := &BindCdnCertRequest{ - CertId: certId, - DomainId: &domainId, - } - - reqBts, err := json.Marshal(req) - if err != nil { - return nil, err - } - - reqMap := make(map[string]interface{}) - err = json.Unmarshal(reqBts, &reqMap) - if err != nil { - return nil, err - } - - respBts, err := c.sendReq(http.MethodPost, "cdn/cert/bind.json", reqMap, true) - if err != nil { - return nil, err - } - - resp := &BindCdnCertResponse{} - err = json.Unmarshal(respBts, resp) - if err != nil { - return nil, err - } - if resp.Code != nil && *resp.Code != 0 && *resp.Code != 200 { - return nil, fmt.Errorf("dogecloud api error, code: %d, msg: %s", *resp.Code, *resp.Message) - } - - return resp, nil -} - -// 调用多吉云的 API。 -// https://docs.dogecloud.com/cdn/api-access-token?id=go -// -// 入参: -// - method:GET 或 POST -// - path:是调用的 API 接口地址,包含 URL 请求参数 QueryString,例如:/console/vfetch/add.json?url=xxx&a=1&b=2 -// - data:POST 的数据,对象,例如 {a: 1, b: 2},传递此参数表示不是 GET 请求而是 POST 请求 -// - jsonMode:数据 data 是否以 JSON 格式请求,默认为 false 则使用表单形式(a=1&b=2) -func (c *Client) sendReq(method string, path string, data map[string]interface{}, jsonMode bool) ([]byte, error) { - body := "" - mime := "" - if jsonMode { - _body, err := json.Marshal(data) - if err != nil { - return nil, err + if resp != nil { + json.Unmarshal(resp.Body(), &res) } - body = string(_body) - mime = "application/json" - } else { - values := url.Values{} - for k, v := range data { - values.Set(k, v.(string)) + return resp, err + } + + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) + } else { + if tcode := res.GetCode(); tcode != 0 && tcode != 200 { + return resp, fmt.Errorf("sdkerr: code='%d', msg='%s'", tcode, res.GetMessage()) + } } - body = values.Encode() - mime = "application/x-www-form-urlencoded" } - path = strings.TrimPrefix(path, "/") - signStr := "/" + path + "\n" + body - hmacObj := hmac.New(sha1.New, []byte(c.secretKey)) - hmacObj.Write([]byte(signStr)) - sign := hex.EncodeToString(hmacObj.Sum(nil)) - auth := fmt.Sprintf("TOKEN %s:%s", c.accessKey, sign) - - req, err := http.NewRequest(method, fmt.Sprintf("%s/%s", dogeHost, path), strings.NewReader(body)) - if err != nil { - return nil, err - } - req.Header.Set("Content-Type", mime) - req.Header.Set("Authorization", auth) - - client := http.Client{} - resp, err := client.Do(req) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - bytes, err := io.ReadAll(resp.Body) - if err != nil { - return nil, err - } - - return bytes, nil + return resp, nil } diff --git a/internal/pkg/sdk3rd/dogecloud/models.go b/internal/pkg/sdk3rd/dogecloud/models.go deleted file mode 100644 index 8dd78a3b..00000000 --- a/internal/pkg/sdk3rd/dogecloud/models.go +++ /dev/null @@ -1,31 +0,0 @@ -package dogecloud - -type BaseResponse struct { - Code *int `json:"code,omitempty"` - Message *string `json:"msg,omitempty"` -} - -type UploadCdnCertRequest struct { - Note string `json:"note"` - Certificate string `json:"cert"` - PrivateKey string `json:"private"` -} - -type UploadCdnCertResponseData struct { - Id int64 `json:"id"` -} - -type UploadCdnCertResponse struct { - BaseResponse - Data *UploadCdnCertResponseData `json:"data,omitempty"` -} - -type BindCdnCertRequest struct { - CertId int64 `json:"id"` - DomainId *int64 `json:"did,omitempty"` - Domain *string `json:"domain,omitempty"` -} - -type BindCdnCertResponse struct { - BaseResponse -} diff --git a/internal/pkg/sdk3rd/dogecloud/types.go b/internal/pkg/sdk3rd/dogecloud/types.go new file mode 100644 index 00000000..368b62a0 --- /dev/null +++ b/internal/pkg/sdk3rd/dogecloud/types.go @@ -0,0 +1,29 @@ +package dogecloud + +type apiResponse interface { + GetCode() int + GetMessage() string +} + +type apiResponseBase struct { + Code *int `json:"code,omitempty"` + Message *string `json:"msg,omitempty"` +} + +func (r *apiResponseBase) GetCode() int { + if r.Code == nil { + return 0 + } + + return *r.Code +} + +func (r *apiResponseBase) GetMessage() string { + if r.Message == nil { + return "" + } + + return *r.Message +} + +var _ apiResponse = (*apiResponseBase)(nil) diff --git a/internal/pkg/sdk3rd/flexcdn/api.go b/internal/pkg/sdk3rd/flexcdn/api.go deleted file mode 100644 index 5008fdf4..00000000 --- a/internal/pkg/sdk3rd/flexcdn/api.go +++ /dev/null @@ -1,48 +0,0 @@ -package flexcdn - -import ( - "encoding/json" - "fmt" - "net/http" - "time" -) - -func (c *Client) ensureAccessTokenExists() error { - c.accessTokenMtx.Lock() - defer c.accessTokenMtx.Unlock() - if c.accessToken != "" && c.accessTokenExp.After(time.Now()) { - return nil - } - - req := &getAPIAccessTokenRequest{ - Type: c.apiRole, - AccessKeyId: c.accessKeyId, - AccessKey: c.accessKey, - } - res, err := c.sendRequest(http.MethodPost, "/APIAccessTokenService/getAPIAccessToken", req) - if err != nil { - return err - } - - resp := &getAPIAccessTokenResponse{} - if err := json.Unmarshal(res.Body(), &resp); err != nil { - return fmt.Errorf("flexcdn api error: failed to unmarshal response: %w", err) - } else if resp.GetCode() != 200 { - return fmt.Errorf("flexcdn get access token failed: code='%d', message='%s'", resp.GetCode(), resp.GetMessage()) - } - - c.accessToken = resp.Data.Token - c.accessTokenExp = time.Unix(resp.Data.ExpiresAt, 0) - - return nil -} - -func (c *Client) UpdateSSLCert(req *UpdateSSLCertRequest) (*UpdateSSLCertResponse, error) { - if err := c.ensureAccessTokenExists(); err != nil { - return nil, err - } - - resp := &UpdateSSLCertResponse{} - err := c.sendRequestWithResult(http.MethodPost, "/SSLCertService/updateSSLCert", req, resp) - return resp, err -} diff --git a/internal/pkg/sdk3rd/flexcdn/api_update_ssl_cert.go b/internal/pkg/sdk3rd/flexcdn/api_update_ssl_cert.go new file mode 100644 index 00000000..13cf3709 --- /dev/null +++ b/internal/pkg/sdk3rd/flexcdn/api_update_ssl_cert.go @@ -0,0 +1,50 @@ +package flexcdn + +import ( + "context" + "net/http" +) + +type UpdateSSLCertRequest struct { + SSLCertId int64 `json:"sslCertId"` + IsOn bool `json:"isOn"` + Name string `json:"name"` + Description string `json:"description"` + ServerName string `json:"serverName"` + IsCA bool `json:"isCA"` + CertData string `json:"certData"` + KeyData string `json:"keyData"` + TimeBeginAt int64 `json:"timeBeginAt"` + TimeEndAt int64 `json:"timeEndAt"` + DNSNames []string `json:"dnsNames"` + CommonNames []string `json:"commonNames"` +} + +type UpdateSSLCertResponse struct { + apiResponseBase +} + +func (c *Client) UpdateSSLCert(req *UpdateSSLCertRequest) (*UpdateSSLCertResponse, error) { + return c.UpdateSSLCertWithContext(context.Background(), req) +} + +func (c *Client) UpdateSSLCertWithContext(ctx context.Context, req *UpdateSSLCertRequest) (*UpdateSSLCertResponse, error) { + if err := c.ensureAccessTokenExists(); err != nil { + return nil, err + } + + httpreq, err := c.newRequest(http.MethodPost, "/SSLCertService/updateSSLCert") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &UpdateSSLCertResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/flexcdn/client.go b/internal/pkg/sdk3rd/flexcdn/client.go index 0844ffa5..3d097a81 100644 --- a/internal/pkg/sdk3rd/flexcdn/client.go +++ b/internal/pkg/sdk3rd/flexcdn/client.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "net/http" + "net/url" "strings" "sync" "time" @@ -24,7 +25,26 @@ type Client struct { client *resty.Client } -func NewClient(serverUrl, apiRole, accessKeyId, accessKey string) *Client { +func NewClient(serverUrl, apiRole, accessKeyId, accessKey string) (*Client, error) { + if serverUrl == "" { + return nil, fmt.Errorf("sdkerr: unset serverUrl") + } + if _, err := url.Parse(serverUrl); err != nil { + return nil, fmt.Errorf("sdkerr: invalid serverUrl: %w", err) + } + if apiRole == "" { + return nil, fmt.Errorf("sdkerr: unset apiRole") + } + if apiRole != "user" && apiRole != "admin" { + return nil, fmt.Errorf("sdkerr: invalid apiRole") + } + if accessKeyId == "" { + return nil, fmt.Errorf("sdkerr: unset accessKeyId") + } + if accessKey == "" { + return nil, fmt.Errorf("sdkerr: unset accessKey") + } + client := &Client{ apiRole: apiRole, accessKeyId: accessKeyId, @@ -32,6 +52,8 @@ func NewClient(serverUrl, apiRole, accessKeyId, accessKey string) *Client { } client.client = resty.New(). SetBaseURL(strings.TrimRight(serverUrl, "/")). + SetHeader("Accept", "application/json"). + SetHeader("Content-Type", "application/json"). SetHeader("User-Agent", "certimate"). SetPreRequestHook(func(c *resty.Client, req *http.Request) error { if client.accessToken != "" { @@ -41,62 +63,111 @@ func NewClient(serverUrl, apiRole, accessKeyId, accessKey string) *Client { return nil }) - return client + return client, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { +func (c *Client) SetTimeout(timeout time.Duration) *Client { c.client.SetTimeout(timeout) return c } -func (c *Client) WithTLSConfig(config *tls.Config) *Client { +func (c *Client) SetTLSConfig(config *tls.Config) *Client { c.client.SetTLSClientConfig(config) return c } -func (c *Client) sendRequest(method string, path string, params interface{}) (*resty.Response, error) { - req := c.client.R() - if strings.EqualFold(method, http.MethodGet) { - qs := make(map[string]string) - if params != nil { - temp := make(map[string]any) - jsonb, _ := json.Marshal(params) - json.Unmarshal(jsonb, &temp) - for k, v := range temp { - if v != nil { - qs[k] = fmt.Sprintf("%v", v) - } - } - } - - req = req.SetQueryParams(qs) - } else { - req = req.SetHeader("Content-Type", "application/json").SetBody(params) +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") } - resp, err := req.Execute(method, path) + req := c.client.R() + req.Method = method + req.URL = path + return req, nil +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + // WARN: + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. + + resp, err := req.Send() if err != nil { - return resp, fmt.Errorf("flexcdn api error: failed to send request: %w", err) + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) } else if resp.IsError() { - return resp, fmt.Errorf("flexcdn api error: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) } return resp, nil } -func (c *Client) sendRequestWithResult(method string, path string, params interface{}, result BaseResponse) error { - resp, err := c.sendRequest(method, path, params) - if err != nil { - if resp != nil { - json.Unmarshal(resp.Body(), &result) - } - return err +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") } - if err := json.Unmarshal(resp.Body(), &result); err != nil { - return fmt.Errorf("flexcdn api error: failed to unmarshal response: %w", err) - } else if errcode := result.GetCode(); errcode != 200 { - return fmt.Errorf("flexcdn api error: code='%d', message='%s'", errcode, result.GetMessage()) + resp, err := c.doRequest(req) + if err != nil { + if resp != nil { + json.Unmarshal(resp.Body(), &res) + } + return resp, err + } + + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) + } else { + if tcode := res.GetCode(); tcode != 200 { + return resp, fmt.Errorf("sdkerr: code='%d', message='%s'", tcode, res.GetMessage()) + } + } + } + + return resp, nil +} + +func (c *Client) ensureAccessTokenExists() error { + c.accessTokenMtx.Lock() + defer c.accessTokenMtx.Unlock() + if c.accessToken != "" && c.accessTokenExp.After(time.Now()) { + return nil + } + + httpreq, err := c.newRequest(http.MethodPost, "/APIAccessTokenService/getAPIAccessToken") + if err != nil { + return err + } else { + httpreq.SetBody(map[string]string{ + "type": c.apiRole, + "accessKeyId": c.accessKeyId, + "accessKey": c.accessKey, + }) + } + + type getAPIAccessTokenResponse struct { + apiResponseBase + Data *struct { + Token string `json:"token"` + ExpiresAt int64 `json:"expiresAt"` + } `json:"data,omitempty"` + } + + result := &getAPIAccessTokenResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return err + } else if code := result.GetCode(); code != 200 { + return fmt.Errorf("sdkerr: failed to get flexcdn access token: code='%d', message='%s'", code, result.GetMessage()) + } else { + c.accessToken = result.Data.Token + c.accessTokenExp = time.Unix(result.Data.ExpiresAt, 0) } return nil diff --git a/internal/pkg/sdk3rd/flexcdn/models.go b/internal/pkg/sdk3rd/flexcdn/models.go deleted file mode 100644 index c976eccc..00000000 --- a/internal/pkg/sdk3rd/flexcdn/models.go +++ /dev/null @@ -1,52 +0,0 @@ -package flexcdn - -type BaseResponse interface { - GetCode() int32 - GetMessage() string -} - -type baseResponse struct { - Code int32 `json:"code"` - Message string `json:"message"` -} - -func (r *baseResponse) GetCode() int32 { - return r.Code -} - -func (r *baseResponse) GetMessage() string { - return r.Message -} - -type getAPIAccessTokenRequest struct { - Type string `json:"type"` - AccessKeyId string `json:"accessKeyId"` - AccessKey string `json:"accessKey"` -} - -type getAPIAccessTokenResponse struct { - baseResponse - Data *struct { - Token string `json:"token"` - ExpiresAt int64 `json:"expiresAt"` - } `json:"data,omitempty"` -} - -type UpdateSSLCertRequest struct { - SSLCertId int64 `json:"sslCertId"` - IsOn bool `json:"isOn"` - Name string `json:"name"` - Description string `json:"description"` - ServerName string `json:"serverName"` - IsCA bool `json:"isCA"` - CertData string `json:"certData"` - KeyData string `json:"keyData"` - TimeBeginAt int64 `json:"timeBeginAt"` - TimeEndAt int64 `json:"timeEndAt"` - DNSNames []string `json:"dnsNames"` - CommonNames []string `json:"commonNames"` -} - -type UpdateSSLCertResponse struct { - baseResponse -} diff --git a/internal/pkg/sdk3rd/flexcdn/types.go b/internal/pkg/sdk3rd/flexcdn/types.go new file mode 100644 index 00000000..21d4372c --- /dev/null +++ b/internal/pkg/sdk3rd/flexcdn/types.go @@ -0,0 +1,21 @@ +package flexcdn + +type apiResponse interface { + GetCode() int32 + GetMessage() string +} + +type apiResponseBase struct { + Code int32 `json:"code"` + Message string `json:"message"` +} + +func (r *apiResponseBase) GetCode() int32 { + return r.Code +} + +func (r *apiResponseBase) GetMessage() string { + return r.Message +} + +var _ apiResponse = (*apiResponseBase)(nil) diff --git a/internal/pkg/sdk3rd/gcore/common/endpoint.go b/internal/pkg/sdk3rd/gcore/endpoint.go similarity index 100% rename from internal/pkg/sdk3rd/gcore/common/endpoint.go rename to internal/pkg/sdk3rd/gcore/endpoint.go diff --git a/internal/pkg/sdk3rd/gcore/common/signer.go b/internal/pkg/sdk3rd/gcore/signer.go similarity index 100% rename from internal/pkg/sdk3rd/gcore/common/signer.go rename to internal/pkg/sdk3rd/gcore/signer.go diff --git a/internal/pkg/sdk3rd/gname/api.go b/internal/pkg/sdk3rd/gname/api.go deleted file mode 100644 index 16b80065..00000000 --- a/internal/pkg/sdk3rd/gname/api.go +++ /dev/null @@ -1,25 +0,0 @@ -package gname - -func (c *Client) AddDomainResolution(req *AddDomainResolutionRequest) (*AddDomainResolutionResponse, error) { - resp := &AddDomainResolutionResponse{} - err := c.sendRequestWithResult("/api/resolution/add", req, resp) - return resp, err -} - -func (c *Client) ModifyDomainResolution(req *ModifyDomainResolutionRequest) (*ModifyDomainResolutionResponse, error) { - resp := &ModifyDomainResolutionResponse{} - err := c.sendRequestWithResult("/api/resolution/edit", req, resp) - return resp, err -} - -func (c *Client) DeleteDomainResolution(req *DeleteDomainResolutionRequest) (*DeleteDomainResolutionResponse, error) { - resp := &DeleteDomainResolutionResponse{} - err := c.sendRequestWithResult("/api/resolution/delete", req, resp) - return resp, err -} - -func (c *Client) ListDomainResolution(req *ListDomainResolutionRequest) (*ListDomainResolutionResponse, error) { - resp := &ListDomainResolutionResponse{} - err := c.sendRequestWithResult("/api/resolution/list", req, resp) - return resp, err -} diff --git a/internal/pkg/sdk3rd/gname/api_add_domain_resolution.go b/internal/pkg/sdk3rd/gname/api_add_domain_resolution.go new file mode 100644 index 00000000..ed5f687a --- /dev/null +++ b/internal/pkg/sdk3rd/gname/api_add_domain_resolution.go @@ -0,0 +1,42 @@ +package gname + +import ( + "context" + "encoding/json" + "net/http" +) + +type AddDomainResolutionRequest struct { + ZoneName *string `json:"ym,omitempty"` + RecordType *string `json:"lx,omitempty"` + RecordName *string `json:"zj,omitempty"` + RecordValue *string `json:"jlz,omitempty"` + MX *int32 `json:"mx,omitempty"` + TTL *int32 `json:"ttl,omitempty"` +} + +type AddDomainResolutionResponse struct { + apiResponseBase + + Data json.Number `json:"data"` +} + +func (c *Client) AddDomainResolution(req *AddDomainResolutionRequest) (*AddDomainResolutionResponse, error) { + return c.AddDomainResolutionWithContext(context.Background(), req) +} + +func (c *Client) AddDomainResolutionWithContext(ctx context.Context, req *AddDomainResolutionRequest) (*AddDomainResolutionResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/api/resolution/add", req) + if err != nil { + return nil, err + } else { + httpreq.SetContext(ctx) + } + + result := &AddDomainResolutionResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/gname/api_delete_domain_resolution.go b/internal/pkg/sdk3rd/gname/api_delete_domain_resolution.go new file mode 100644 index 00000000..a2125fb3 --- /dev/null +++ b/internal/pkg/sdk3rd/gname/api_delete_domain_resolution.go @@ -0,0 +1,35 @@ +package gname + +import ( + "context" + "net/http" +) + +type DeleteDomainResolutionRequest struct { + ZoneName *string `json:"ym,omitempty"` + RecordID *int64 `json:"jxid,omitempty"` +} + +type DeleteDomainResolutionResponse struct { + apiResponseBase +} + +func (c *Client) DeleteDomainResolution(req *DeleteDomainResolutionRequest) (*DeleteDomainResolutionResponse, error) { + return c.DeleteDomainResolutionWithContext(context.Background(), req) +} + +func (c *Client) DeleteDomainResolutionWithContext(ctx context.Context, req *DeleteDomainResolutionRequest) (*DeleteDomainResolutionResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/api/resolution/delete", req) + if err != nil { + return nil, err + } else { + httpreq.SetContext(ctx) + } + + result := &DeleteDomainResolutionResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/gname/api_list_domain_resolution.go b/internal/pkg/sdk3rd/gname/api_list_domain_resolution.go new file mode 100644 index 00000000..98832fc1 --- /dev/null +++ b/internal/pkg/sdk3rd/gname/api_list_domain_resolution.go @@ -0,0 +1,41 @@ +package gname + +import ( + "context" + "net/http" +) + +type ListDomainResolutionRequest struct { + ZoneName *string `json:"ym,omitempty"` + Page *int32 `json:"page,omitempty"` + PageSize *int32 `json:"limit,omitempty"` +} + +type ListDomainResolutionResponse struct { + apiResponseBase + + Count int32 `json:"count"` + Data []*DomainResolutionRecordord `json:"data"` + Page int32 `json:"page"` + PageSize int32 `json:"pagesize"` +} + +func (c *Client) ListDomainResolution(req *ListDomainResolutionRequest) (*ListDomainResolutionResponse, error) { + return c.ListDomainResolutionWithContext(context.Background(), req) +} + +func (c *Client) ListDomainResolutionWithContext(ctx context.Context, req *ListDomainResolutionRequest) (*ListDomainResolutionResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/api/resolution/list", req) + if err != nil { + return nil, err + } else { + httpreq.SetContext(ctx) + } + + result := &ListDomainResolutionResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/gname/api_modify_domain_resolution.go b/internal/pkg/sdk3rd/gname/api_modify_domain_resolution.go new file mode 100644 index 00000000..883f4c41 --- /dev/null +++ b/internal/pkg/sdk3rd/gname/api_modify_domain_resolution.go @@ -0,0 +1,40 @@ +package gname + +import ( + "context" + "net/http" +) + +type ModifyDomainResolutionRequest struct { + ID *int64 `json:"jxid,omitempty"` + ZoneName *string `json:"ym,omitempty"` + RecordType *string `json:"lx,omitempty"` + RecordName *string `json:"zj,omitempty"` + RecordValue *string `json:"jlz,omitempty"` + MX *int32 `json:"mx,omitempty"` + TTL *int32 `json:"ttl,omitempty"` +} + +type ModifyDomainResolutionResponse struct { + apiResponseBase +} + +func (c *Client) ModifyDomainResolution(req *ModifyDomainResolutionRequest) (*ModifyDomainResolutionResponse, error) { + return c.ModifyDomainResolutionWithContext(context.Background(), req) +} + +func (c *Client) ModifyDomainResolutionWithContext(ctx context.Context, req *ModifyDomainResolutionRequest) (*ModifyDomainResolutionResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/api/resolution/edit", req) + if err != nil { + return nil, err + } else { + httpreq.SetContext(ctx) + } + + result := &ModifyDomainResolutionResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/gname/client.go b/internal/pkg/sdk3rd/gname/client.go index 843785a5..5fd26e02 100644 --- a/internal/pkg/sdk3rd/gname/client.go +++ b/internal/pkg/sdk3rd/gname/client.go @@ -19,9 +19,17 @@ type Client struct { client *resty.Client } -func NewClient(appId, appKey string) *Client { +func NewClient(appId, appKey string) (*Client, error) { + if appId == "" { + return nil, fmt.Errorf("sdkerr: unset appId") + } + if appKey == "" { + return nil, fmt.Errorf("sdkerr: unset appKey") + } + client := resty.New(). SetBaseURL("http://api.gname.com"). + SetHeader("Accept", "application/json"). SetHeader("Content-Type", "application/x-www-form-urlencoded"). SetHeader("User-Agent", "certimate") @@ -29,15 +37,93 @@ func NewClient(appId, appKey string) *Client { appId: appId, appKey: appKey, client: client, - } + }, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { +func (c *Client) SetTimeout(timeout time.Duration) *Client { c.client.SetTimeout(timeout) return c } -func (c *Client) generateSignature(params map[string]string) string { +func (c *Client) newRequest(method string, path string, params any) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") + } + + data := make(map[string]string) + if params != nil { + temp := make(map[string]any) + jsonb, _ := json.Marshal(params) + json.Unmarshal(jsonb, &temp) + for k, v := range temp { + if v == nil { + continue + } + + data[k] = fmt.Sprintf("%v", v) + } + } + + data["appid"] = c.appId + data["gntime"] = fmt.Sprintf("%d", time.Now().Unix()) + data["gntoken"] = generateSignature(data, c.appKey) + + req := c.client.R() + req.Method = method + req.URL = path + req.SetFormData(data) + return req, nil +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + // WARN: + // PLEASE DO NOT USE `req.SetBody` or `req.SetFormData` HERE! USE `newRequest` INSTEAD. + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. + + resp, err := req.Send() + if err != nil { + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) + } else if resp.IsError() { + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) + } + + return resp, nil +} + +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + resp, err := c.doRequest(req) + if err != nil { + if resp != nil { + json.Unmarshal(resp.Body(), &res) + } + return resp, err + } + + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) + } else { + if tcode := res.GetCode(); tcode != 1 { + return resp, fmt.Errorf("sdkerr: api error: code='%d', message='%s'", tcode, res.GetMessage()) + } + } + } + + return resp, nil +} + +func generateSignature(params map[string]string, appKey string) string { // Step 1: Sort parameters by ASCII order var keys []string for k := range params { @@ -54,51 +140,9 @@ func (c *Client) generateSignature(params map[string]string) string { stringA := strings.Join(pairs, "&") // Step 3: Append appkey to create string B - stringB := stringA + c.appKey + stringB := stringA + appKey // Step 4: Calculate MD5 and convert to uppercase hash := md5.Sum([]byte(stringB)) return strings.ToUpper(fmt.Sprintf("%x", hash)) } - -func (c *Client) sendRequest(path string, params interface{}) (*resty.Response, error) { - data := make(map[string]string) - if params != nil { - temp := make(map[string]any) - jsonb, _ := json.Marshal(params) - json.Unmarshal(jsonb, &temp) - for k, v := range temp { - if v != nil { - data[k] = fmt.Sprintf("%v", v) - } - } - } - data["appid"] = c.appId - data["gntime"] = fmt.Sprintf("%d", time.Now().Unix()) - data["gntoken"] = c.generateSignature(data) - - req := c.client.R().SetFormData(data) - resp, err := req.Post(path) - if err != nil { - return resp, fmt.Errorf("gname api error: failed to send request: %w", err) - } else if resp.IsError() { - return resp, fmt.Errorf("gname api error: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) - } - - return resp, nil -} - -func (c *Client) sendRequestWithResult(path string, params interface{}, result BaseResponse) error { - resp, err := c.sendRequest(path, params) - if err != nil { - return err - } - - if err := json.Unmarshal(resp.Body(), &result); err != nil { - return fmt.Errorf("gname api error: failed to unmarshal response: %w", err) - } else if errcode := result.GetCode(); errcode != 1 { - return fmt.Errorf("gname api error: code='%d', message='%s'", errcode, result.GetMessage()) - } - - return nil -} diff --git a/internal/pkg/sdk3rd/gname/models.go b/internal/pkg/sdk3rd/gname/models.go deleted file mode 100644 index a50b609b..00000000 --- a/internal/pkg/sdk3rd/gname/models.go +++ /dev/null @@ -1,81 +0,0 @@ -package gname - -import "encoding/json" - -type BaseResponse interface { - GetCode() int32 - GetMessage() string -} - -type baseResponse struct { - Code int32 `json:"code"` - Message string `json:"msg"` -} - -func (r *baseResponse) GetCode() int32 { - return r.Code -} - -func (r *baseResponse) GetMessage() string { - return r.Message -} - -type AddDomainResolutionRequest struct { - ZoneName string `json:"ym"` - RecordType string `json:"lx"` - RecordName string `json:"zj"` - RecordValue string `json:"jlz"` - MX int32 `json:"mx"` - TTL int32 `json:"ttl"` -} - -type AddDomainResolutionResponse struct { - baseResponse - Data json.Number `json:"data"` -} - -type ModifyDomainResolutionRequest struct { - ID int64 `json:"jxid"` - ZoneName string `json:"ym"` - RecordType string `json:"lx"` - RecordName string `json:"zj"` - RecordValue string `json:"jlz"` - MX int32 `json:"mx"` - TTL int32 `json:"ttl"` -} - -type ModifyDomainResolutionResponse struct { - baseResponse -} - -type DeleteDomainResolutionRequest struct { - ZoneName string `json:"ym"` - RecordID int64 `json:"jxid"` -} - -type DeleteDomainResolutionResponse struct { - baseResponse -} - -type ListDomainResolutionRequest struct { - ZoneName string `json:"ym"` - Page *int32 `json:"page,omitempty"` - PageSize *int32 `json:"limit,omitempty"` -} - -type ListDomainResolutionResponse struct { - baseResponse - Count int32 `json:"count"` - Data []*ResolutionRecord `json:"data"` - Page int32 `json:"page"` - PageSize int32 `json:"pagesize"` -} - -type ResolutionRecord struct { - ID json.Number `json:"id"` - ZoneName string `json:"ym"` - RecordType string `json:"lx"` - RecordName string `json:"zjt"` - RecordValue string `json:"jxz"` - MX int32 `json:"mx"` -} diff --git a/internal/pkg/sdk3rd/gname/types.go b/internal/pkg/sdk3rd/gname/types.go new file mode 100644 index 00000000..5b1373ea --- /dev/null +++ b/internal/pkg/sdk3rd/gname/types.go @@ -0,0 +1,32 @@ +package gname + +import "encoding/json" + +type apiResponse interface { + GetCode() int32 + GetMessage() string +} + +type apiResponseBase struct { + Code int32 `json:"code"` + Message string `json:"msg"` +} + +func (r *apiResponseBase) GetCode() int32 { + return r.Code +} + +func (r *apiResponseBase) GetMessage() string { + return r.Message +} + +var _ apiResponse = (*apiResponseBase)(nil) + +type DomainResolutionRecordord struct { + ID json.Number `json:"id"` + ZoneName string `json:"ym"` + RecordType string `json:"lx"` + RecordName string `json:"zjt"` + RecordValue string `json:"jxz"` + MX int32 `json:"mx"` +} diff --git a/internal/pkg/sdk3rd/goedge/api.go b/internal/pkg/sdk3rd/goedge/api.go deleted file mode 100644 index 4589f70c..00000000 --- a/internal/pkg/sdk3rd/goedge/api.go +++ /dev/null @@ -1,48 +0,0 @@ -package goedge - -import ( - "encoding/json" - "fmt" - "net/http" - "time" -) - -func (c *Client) ensureAccessTokenExists() error { - c.accessTokenMtx.Lock() - defer c.accessTokenMtx.Unlock() - if c.accessToken != "" && c.accessTokenExp.After(time.Now()) { - return nil - } - - req := &getAPIAccessTokenRequest{ - Type: c.apiRole, - AccessKeyId: c.accessKeyId, - AccessKey: c.accessKey, - } - res, err := c.sendRequest(http.MethodPost, "/APIAccessTokenService/getAPIAccessToken", req) - if err != nil { - return err - } - - resp := &getAPIAccessTokenResponse{} - if err := json.Unmarshal(res.Body(), &resp); err != nil { - return fmt.Errorf("goedge api error: failed to unmarshal response: %w", err) - } else if resp.GetCode() != 200 { - return fmt.Errorf("goedge get access token failed: code='%d', message='%s'", resp.GetCode(), resp.GetMessage()) - } - - c.accessToken = resp.Data.Token - c.accessTokenExp = time.Unix(resp.Data.ExpiresAt, 0) - - return nil -} - -func (c *Client) UpdateSSLCert(req *UpdateSSLCertRequest) (*UpdateSSLCertResponse, error) { - if err := c.ensureAccessTokenExists(); err != nil { - return nil, err - } - - resp := &UpdateSSLCertResponse{} - err := c.sendRequestWithResult(http.MethodPost, "/SSLCertService/updateSSLCert", req, resp) - return resp, err -} diff --git a/internal/pkg/sdk3rd/goedge/api_update_ssl_cert.go b/internal/pkg/sdk3rd/goedge/api_update_ssl_cert.go new file mode 100644 index 00000000..0aa68353 --- /dev/null +++ b/internal/pkg/sdk3rd/goedge/api_update_ssl_cert.go @@ -0,0 +1,50 @@ +package goedge + +import ( + "context" + "net/http" +) + +type UpdateSSLCertRequest struct { + SSLCertId int64 `json:"sslCertId"` + IsOn bool `json:"isOn"` + Name string `json:"name"` + Description string `json:"description"` + ServerName string `json:"serverName"` + IsCA bool `json:"isCA"` + CertData string `json:"certData"` + KeyData string `json:"keyData"` + TimeBeginAt int64 `json:"timeBeginAt"` + TimeEndAt int64 `json:"timeEndAt"` + DNSNames []string `json:"dnsNames"` + CommonNames []string `json:"commonNames"` +} + +type UpdateSSLCertResponse struct { + apiResponseBase +} + +func (c *Client) UpdateSSLCert(req *UpdateSSLCertRequest) (*UpdateSSLCertResponse, error) { + return c.UpdateSSLCertWithContext(context.Background(), req) +} + +func (c *Client) UpdateSSLCertWithContext(ctx context.Context, req *UpdateSSLCertRequest) (*UpdateSSLCertResponse, error) { + if err := c.ensureAccessTokenExists(); err != nil { + return nil, err + } + + httpreq, err := c.newRequest(http.MethodPost, "/SSLCertService/updateSSLCert") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &UpdateSSLCertResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/goedge/client.go b/internal/pkg/sdk3rd/goedge/client.go index bc87734a..52fdd8d8 100644 --- a/internal/pkg/sdk3rd/goedge/client.go +++ b/internal/pkg/sdk3rd/goedge/client.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "net/http" + "net/url" "strings" "sync" "time" @@ -24,7 +25,26 @@ type Client struct { client *resty.Client } -func NewClient(serverUrl, apiRole, accessKeyId, accessKey string) *Client { +func NewClient(serverUrl, apiRole, accessKeyId, accessKey string) (*Client, error) { + if serverUrl == "" { + return nil, fmt.Errorf("sdkerr: unset serverUrl") + } + if _, err := url.Parse(serverUrl); err != nil { + return nil, fmt.Errorf("sdkerr: invalid serverUrl: %w", err) + } + if apiRole == "" { + return nil, fmt.Errorf("sdkerr: unset apiRole") + } + if apiRole != "user" && apiRole != "admin" { + return nil, fmt.Errorf("sdkerr: invalid apiRole") + } + if accessKeyId == "" { + return nil, fmt.Errorf("sdkerr: unset accessKeyId") + } + if accessKey == "" { + return nil, fmt.Errorf("sdkerr: unset accessKey") + } + client := &Client{ apiRole: apiRole, accessKeyId: accessKeyId, @@ -32,6 +52,8 @@ func NewClient(serverUrl, apiRole, accessKeyId, accessKey string) *Client { } client.client = resty.New(). SetBaseURL(strings.TrimRight(serverUrl, "/")). + SetHeader("Accept", "application/json"). + SetHeader("Content-Type", "application/json"). SetHeader("User-Agent", "certimate"). SetPreRequestHook(func(c *resty.Client, req *http.Request) error { if client.accessToken != "" { @@ -41,62 +63,111 @@ func NewClient(serverUrl, apiRole, accessKeyId, accessKey string) *Client { return nil }) - return client + return client, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { +func (c *Client) SetTimeout(timeout time.Duration) *Client { c.client.SetTimeout(timeout) return c } -func (c *Client) WithTLSConfig(config *tls.Config) *Client { +func (c *Client) SetTLSConfig(config *tls.Config) *Client { c.client.SetTLSClientConfig(config) return c } -func (c *Client) sendRequest(method string, path string, params interface{}) (*resty.Response, error) { - req := c.client.R() - if strings.EqualFold(method, http.MethodGet) { - qs := make(map[string]string) - if params != nil { - temp := make(map[string]any) - jsonb, _ := json.Marshal(params) - json.Unmarshal(jsonb, &temp) - for k, v := range temp { - if v != nil { - qs[k] = fmt.Sprintf("%v", v) - } - } - } - - req = req.SetQueryParams(qs) - } else { - req = req.SetHeader("Content-Type", "application/json").SetBody(params) +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") } - resp, err := req.Execute(method, path) + req := c.client.R() + req.Method = method + req.URL = path + return req, nil +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + // WARN: + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. + + resp, err := req.Send() if err != nil { - return resp, fmt.Errorf("goedge api error: failed to send request: %w", err) + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) } else if resp.IsError() { - return resp, fmt.Errorf("goedge api error: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) } return resp, nil } -func (c *Client) sendRequestWithResult(method string, path string, params interface{}, result BaseResponse) error { - resp, err := c.sendRequest(method, path, params) - if err != nil { - if resp != nil { - json.Unmarshal(resp.Body(), &result) - } - return err +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") } - if err := json.Unmarshal(resp.Body(), &result); err != nil { - return fmt.Errorf("goedge api error: failed to unmarshal response: %w", err) - } else if errcode := result.GetCode(); errcode != 200 { - return fmt.Errorf("goedge api error: code='%d', message='%s'", errcode, result.GetMessage()) + resp, err := c.doRequest(req) + if err != nil { + if resp != nil { + json.Unmarshal(resp.Body(), &res) + } + return resp, err + } + + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) + } else { + if tcode := res.GetCode(); tcode != 200 { + return resp, fmt.Errorf("sdkerr: code='%d', message='%s'", tcode, res.GetMessage()) + } + } + } + + return resp, nil +} + +func (c *Client) ensureAccessTokenExists() error { + c.accessTokenMtx.Lock() + defer c.accessTokenMtx.Unlock() + if c.accessToken != "" && c.accessTokenExp.After(time.Now()) { + return nil + } + + httpreq, err := c.newRequest(http.MethodPost, "/APIAccessTokenService/getAPIAccessToken") + if err != nil { + return err + } else { + httpreq.SetBody(map[string]string{ + "type": c.apiRole, + "accessKeyId": c.accessKeyId, + "accessKey": c.accessKey, + }) + } + + type getAPIAccessTokenResponse struct { + apiResponseBase + Data *struct { + Token string `json:"token"` + ExpiresAt int64 `json:"expiresAt"` + } `json:"data,omitempty"` + } + + result := &getAPIAccessTokenResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return err + } else if code := result.GetCode(); code != 200 { + return fmt.Errorf("sdkerr: failed to get goedge access token: code='%d', message='%s'", code, result.GetMessage()) + } else { + c.accessToken = result.Data.Token + c.accessTokenExp = time.Unix(result.Data.ExpiresAt, 0) } return nil diff --git a/internal/pkg/sdk3rd/goedge/models.go b/internal/pkg/sdk3rd/goedge/models.go deleted file mode 100644 index d19bb558..00000000 --- a/internal/pkg/sdk3rd/goedge/models.go +++ /dev/null @@ -1,52 +0,0 @@ -package goedge - -type BaseResponse interface { - GetCode() int32 - GetMessage() string -} - -type baseResponse struct { - Code int32 `json:"code"` - Message string `json:"message"` -} - -func (r *baseResponse) GetCode() int32 { - return r.Code -} - -func (r *baseResponse) GetMessage() string { - return r.Message -} - -type getAPIAccessTokenRequest struct { - Type string `json:"type"` - AccessKeyId string `json:"accessKeyId"` - AccessKey string `json:"accessKey"` -} - -type getAPIAccessTokenResponse struct { - baseResponse - Data *struct { - Token string `json:"token"` - ExpiresAt int64 `json:"expiresAt"` - } `json:"data,omitempty"` -} - -type UpdateSSLCertRequest struct { - SSLCertId int64 `json:"sslCertId"` - IsOn bool `json:"isOn"` - Name string `json:"name"` - Description string `json:"description"` - ServerName string `json:"serverName"` - IsCA bool `json:"isCA"` - CertData string `json:"certData"` - KeyData string `json:"keyData"` - TimeBeginAt int64 `json:"timeBeginAt"` - TimeEndAt int64 `json:"timeEndAt"` - DNSNames []string `json:"dnsNames"` - CommonNames []string `json:"commonNames"` -} - -type UpdateSSLCertResponse struct { - baseResponse -} diff --git a/internal/pkg/sdk3rd/goedge/types.go b/internal/pkg/sdk3rd/goedge/types.go new file mode 100644 index 00000000..75434d6f --- /dev/null +++ b/internal/pkg/sdk3rd/goedge/types.go @@ -0,0 +1,21 @@ +package goedge + +type apiResponse interface { + GetCode() int32 + GetMessage() string +} + +type apiResponseBase struct { + Code int32 `json:"code"` + Message string `json:"message"` +} + +func (r *apiResponseBase) GetCode() int32 { + return r.Code +} + +func (r *apiResponseBase) GetMessage() string { + return r.Message +} + +var _ apiResponse = (*apiResponseBase)(nil) diff --git a/internal/pkg/sdk3rd/lecdn/client-v3/api_update_certificate.go b/internal/pkg/sdk3rd/lecdn/client-v3/api_update_certificate.go new file mode 100644 index 00000000..d9ffa4d9 --- /dev/null +++ b/internal/pkg/sdk3rd/lecdn/client-v3/api_update_certificate.go @@ -0,0 +1,49 @@ +package clientv3 + +import ( + "context" + "fmt" + "net/http" +) + +type UpdateCertificateRequest struct { + Name string `json:"name"` + Description string `json:"description"` + Type string `json:"type"` + SSLPEM string `json:"ssl_pem"` + SSLKey string `json:"ssl_key"` + AutoRenewal bool `json:"auto_renewal"` +} + +type UpdateCertificateResponse struct { + apiResponseBase +} + +func (c *Client) UpdateCertificate(certId int64, req *UpdateCertificateRequest) (*UpdateCertificateResponse, error) { + return c.UpdateCertificateWithContext(context.Background(), certId, req) +} + +func (c *Client) UpdateCertificateWithContext(ctx context.Context, certId int64, req *UpdateCertificateRequest) (*UpdateCertificateResponse, error) { + if certId == 0 { + return nil, fmt.Errorf("sdkerr: unset certId") + } + + if err := c.ensureAccessTokenExists(); err != nil { + return nil, err + } + + httpreq, err := c.newRequest(http.MethodPut, fmt.Sprintf("/certificate/%d", certId)) + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &UpdateCertificateResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/lecdn/client-v3/client.go b/internal/pkg/sdk3rd/lecdn/client-v3/client.go new file mode 100644 index 00000000..72e4b316 --- /dev/null +++ b/internal/pkg/sdk3rd/lecdn/client-v3/client.go @@ -0,0 +1,161 @@ +package clientv3 + +import ( + "crypto/tls" + "encoding/json" + "fmt" + "net/http" + "net/url" + "strings" + "sync" + "time" + + "github.com/go-resty/resty/v2" +) + +type Client struct { + username string + password string + + accessToken string + accessTokenMtx sync.Mutex + + client *resty.Client +} + +func NewClient(serverUrl, username, password string) (*Client, error) { + if serverUrl == "" { + return nil, fmt.Errorf("sdkerr: unset serverUrl") + } + if _, err := url.Parse(serverUrl); err != nil { + return nil, fmt.Errorf("sdkerr: invalid serverUrl: %w", err) + } + if username == "" { + return nil, fmt.Errorf("sdkerr: unset username") + } + if password == "" { + return nil, fmt.Errorf("sdkerr: unset password") + } + + client := &Client{ + username: username, + password: password, + } + client.client = resty.New(). + SetBaseURL(strings.TrimRight(serverUrl, "/")+"/prod-api"). + SetHeader("User-Agent", "certimate"). + SetPreRequestHook(func(c *resty.Client, req *http.Request) error { + if client.accessToken != "" { + req.Header.Set("Authorization", "Bearer "+client.accessToken) + } + + return nil + }) + + return client, nil +} + +func (c *Client) SetTimeout(timeout time.Duration) *Client { + c.client.SetTimeout(timeout) + return c +} + +func (c *Client) SetTLSConfig(config *tls.Config) *Client { + c.client.SetTLSClientConfig(config) + return c +} + +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") + } + + req := c.client.R() + req.Method = method + req.URL = path + return req, nil +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + // WARN: + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. + + resp, err := req.Send() + if err != nil { + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) + } else if resp.IsError() { + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) + } + + return resp, nil +} + +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + resp, err := c.doRequest(req) + if err != nil { + if resp != nil { + json.Unmarshal(resp.Body(), &res) + } + return resp, err + } + + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) + } else { + if tcode := res.GetCode(); tcode != 200 { + return resp, fmt.Errorf("sdkerr: code='%d', message='%s'", tcode, res.GetMessage()) + } + } + } + + return resp, nil +} + +func (c *Client) ensureAccessTokenExists() error { + c.accessTokenMtx.Lock() + defer c.accessTokenMtx.Unlock() + if c.accessToken != "" { + return nil + } + + httpreq, err := c.newRequest(http.MethodPost, "/auth/login") + if err != nil { + return err + } else { + httpreq.SetBody(map[string]string{ + "email": c.username, + "username": c.username, + "password": c.password, + }) + } + + type loginResponse struct { + apiResponseBase + Data *struct { + UserId int64 `json:"user_id"` + Username string `json:"username"` + Token string `json:"token"` + } `json:"data,omitempty"` + } + + result := &loginResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return err + } else { + c.accessToken = result.Data.Token + } + + return nil +} diff --git a/internal/pkg/sdk3rd/lecdn/client-v3/types.go b/internal/pkg/sdk3rd/lecdn/client-v3/types.go new file mode 100644 index 00000000..f1597f42 --- /dev/null +++ b/internal/pkg/sdk3rd/lecdn/client-v3/types.go @@ -0,0 +1,21 @@ +package clientv3 + +type apiResponse interface { + GetCode() int32 + GetMessage() string +} + +type apiResponseBase struct { + Code int32 `json:"code"` + Message string `json:"msg"` +} + +func (r *apiResponseBase) GetCode() int32 { + return r.Code +} + +func (r *apiResponseBase) GetMessage() string { + return r.Message +} + +var _ apiResponse = (*apiResponseBase)(nil) diff --git a/internal/pkg/sdk3rd/lecdn/master-v3/api_update_certificate.go b/internal/pkg/sdk3rd/lecdn/master-v3/api_update_certificate.go new file mode 100644 index 00000000..c7205f73 --- /dev/null +++ b/internal/pkg/sdk3rd/lecdn/master-v3/api_update_certificate.go @@ -0,0 +1,50 @@ +package masterv3 + +import ( + "context" + "fmt" + "net/http" +) + +type UpdateCertificateRequest struct { + ClientId int64 `json:"client_id"` + Name string `json:"name"` + Description string `json:"description"` + Type string `json:"type"` + SSLPEM string `json:"ssl_pem"` + SSLKey string `json:"ssl_key"` + AutoRenewal bool `json:"auto_renewal"` +} + +type UpdateCertificateResponse struct { + apiResponseBase +} + +func (c *Client) UpdateCertificate(certId int64, req *UpdateCertificateRequest) (*UpdateCertificateResponse, error) { + return c.UpdateCertificateWithContext(context.Background(), certId, req) +} + +func (c *Client) UpdateCertificateWithContext(ctx context.Context, certId int64, req *UpdateCertificateRequest) (*UpdateCertificateResponse, error) { + if certId == 0 { + return nil, fmt.Errorf("sdkerr: unset certId") + } + + if err := c.ensureAccessTokenExists(); err != nil { + return nil, err + } + + httpreq, err := c.newRequest(http.MethodPut, fmt.Sprintf("/certificate/%d", certId)) + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &UpdateCertificateResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/lecdn/master-v3/client.go b/internal/pkg/sdk3rd/lecdn/master-v3/client.go new file mode 100644 index 00000000..66700609 --- /dev/null +++ b/internal/pkg/sdk3rd/lecdn/master-v3/client.go @@ -0,0 +1,162 @@ +package masterv3 + +import ( + "crypto/tls" + "encoding/json" + "fmt" + "net/http" + "net/url" + "strings" + "sync" + "time" + + "github.com/go-resty/resty/v2" +) + +type Client struct { + username string + password string + + accessToken string + accessTokenMtx sync.Mutex + + client *resty.Client +} + +func NewClient(serverUrl, username, password string) (*Client, error) { + if serverUrl == "" { + return nil, fmt.Errorf("sdkerr: unset serverUrl") + } + if _, err := url.Parse(serverUrl); err != nil { + return nil, fmt.Errorf("sdkerr: invalid serverUrl: %w", err) + } + if username == "" { + return nil, fmt.Errorf("sdkerr: unset username") + } + if password == "" { + return nil, fmt.Errorf("sdkerr: unset password") + } + + client := &Client{ + username: username, + password: password, + } + client.client = resty.New(). + SetBaseURL(strings.TrimRight(serverUrl, "/")+"/prod-api"). + SetHeader("Accept", "application/json"). + SetHeader("Content-Type", "application/json"). + SetHeader("User-Agent", "certimate"). + SetPreRequestHook(func(c *resty.Client, req *http.Request) error { + if client.accessToken != "" { + req.Header.Set("Authorization", "Bearer "+client.accessToken) + } + + return nil + }) + + return client, nil +} + +func (c *Client) SetTimeout(timeout time.Duration) *Client { + c.client.SetTimeout(timeout) + return c +} + +func (c *Client) SetTLSConfig(config *tls.Config) *Client { + c.client.SetTLSClientConfig(config) + return c +} + +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") + } + + req := c.client.R() + req.Method = method + req.URL = path + return req, nil +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + // WARN: + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. + + resp, err := req.Send() + if err != nil { + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) + } else if resp.IsError() { + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) + } + + return resp, nil +} + +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + resp, err := c.doRequest(req) + if err != nil { + if resp != nil { + json.Unmarshal(resp.Body(), &res) + } + return resp, err + } + + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) + } else { + if tcode := res.GetCode(); tcode != 200 { + return resp, fmt.Errorf("sdkerr: code='%d', message='%s'", tcode, res.GetMessage()) + } + } + } + + return resp, nil +} + +func (c *Client) ensureAccessTokenExists() error { + c.accessTokenMtx.Lock() + defer c.accessTokenMtx.Unlock() + if c.accessToken != "" { + return nil + } + + httpreq, err := c.newRequest(http.MethodPost, "/auth/login") + if err != nil { + return err + } else { + httpreq.SetBody(map[string]string{ + "username": c.username, + "password": c.password, + }) + } + + type loginResponse struct { + apiResponseBase + Data *struct { + UserId int64 `json:"user_id"` + Username string `json:"username"` + Token string `json:"token"` + } `json:"data,omitempty"` + } + + result := &loginResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return err + } else { + c.accessToken = result.Data.Token + } + + return nil +} diff --git a/internal/pkg/sdk3rd/lecdn/master-v3/types.go b/internal/pkg/sdk3rd/lecdn/master-v3/types.go new file mode 100644 index 00000000..35e6d7f1 --- /dev/null +++ b/internal/pkg/sdk3rd/lecdn/master-v3/types.go @@ -0,0 +1,21 @@ +package masterv3 + +type apiResponse interface { + GetCode() int32 + GetMessage() string +} + +type apiResponseBase struct { + Code int32 `json:"code"` + Message string `json:"message"` +} + +func (r *apiResponseBase) GetCode() int32 { + return r.Code +} + +func (r *apiResponseBase) GetMessage() string { + return r.Message +} + +var _ apiResponse = (*apiResponseBase)(nil) diff --git a/internal/pkg/sdk3rd/lecdn/v3/client/api.go b/internal/pkg/sdk3rd/lecdn/v3/client/api.go deleted file mode 100644 index 89f9cdc0..00000000 --- a/internal/pkg/sdk3rd/lecdn/v3/client/api.go +++ /dev/null @@ -1,50 +0,0 @@ -package client - -import ( - "encoding/json" - "fmt" - "net/http" -) - -func (c *Client) ensureAccessTokenExists() error { - c.accessTokenMtx.Lock() - defer c.accessTokenMtx.Unlock() - if c.accessToken != "" { - return nil - } - - req := &loginRequest{ - Email: c.username, - Username: c.username, - Password: c.password, - } - res, err := c.sendRequest(http.MethodPost, "/login", req) - if err != nil { - return err - } - - resp := &loginResponse{} - if err := json.Unmarshal(res.Body(), &resp); err != nil { - return fmt.Errorf("lecdn api error: failed to unmarshal response: %w", err) - } else if resp.GetCode() != 200 { - return fmt.Errorf("lecdn get token failed: code='%d', message='%s'", resp.GetCode(), resp.GetMessage()) - } - - c.accessToken = resp.Data.Token - - return nil -} - -func (c *Client) UpdateCertificate(certId int64, req *UpdateCertificateRequest) (*UpdateCertificateResponse, error) { - if certId == 0 { - return nil, fmt.Errorf("lecdn api error: invalid parameter: CertId") - } - - if err := c.ensureAccessTokenExists(); err != nil { - return nil, err - } - - resp := &UpdateCertificateResponse{} - err := c.sendRequestWithResult(http.MethodPut, fmt.Sprintf("/certificate/%d", certId), req, resp) - return resp, err -} diff --git a/internal/pkg/sdk3rd/lecdn/v3/client/client.go b/internal/pkg/sdk3rd/lecdn/v3/client/client.go deleted file mode 100644 index 4af04d4f..00000000 --- a/internal/pkg/sdk3rd/lecdn/v3/client/client.go +++ /dev/null @@ -1,100 +0,0 @@ -package client - -import ( - "crypto/tls" - "encoding/json" - "fmt" - "net/http" - "strings" - "sync" - "time" - - "github.com/go-resty/resty/v2" -) - -type Client struct { - username string - password string - - accessToken string - accessTokenMtx sync.Mutex - - client *resty.Client -} - -func NewClient(serverUrl, username, password string) *Client { - client := &Client{ - username: username, - password: password, - } - client.client = resty.New(). - SetBaseURL(strings.TrimRight(serverUrl, "/")+"/prod-api"). - SetHeader("User-Agent", "certimate"). - SetPreRequestHook(func(c *resty.Client, req *http.Request) error { - if client.accessToken != "" { - req.Header.Set("Authorization", "Bearer "+client.accessToken) - } - - return nil - }) - - return client -} - -func (c *Client) WithTimeout(timeout time.Duration) *Client { - c.client.SetTimeout(timeout) - return c -} - -func (c *Client) WithTLSConfig(config *tls.Config) *Client { - c.client.SetTLSClientConfig(config) - return c -} - -func (c *Client) sendRequest(method string, path string, params interface{}) (*resty.Response, error) { - req := c.client.R() - if strings.EqualFold(method, http.MethodGet) { - qs := make(map[string]string) - if params != nil { - temp := make(map[string]any) - jsonb, _ := json.Marshal(params) - json.Unmarshal(jsonb, &temp) - for k, v := range temp { - if v != nil { - qs[k] = fmt.Sprintf("%v", v) - } - } - } - - req = req.SetQueryParams(qs) - } else { - req = req.SetHeader("Content-Type", "application/json").SetBody(params) - } - - resp, err := req.Execute(method, path) - if err != nil { - return resp, fmt.Errorf("lecdn api error: failed to send request: %w", err) - } else if resp.IsError() { - return resp, fmt.Errorf("lecdn api error: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) - } - - return resp, nil -} - -func (c *Client) sendRequestWithResult(method string, path string, params interface{}, result BaseResponse) error { - resp, err := c.sendRequest(method, path, params) - if err != nil { - if resp != nil { - json.Unmarshal(resp.Body(), &result) - } - return err - } - - if err := json.Unmarshal(resp.Body(), &result); err != nil { - return fmt.Errorf("lecdn api error: failed to unmarshal response: %w", err) - } else if errcode := result.GetCode(); errcode != 200 { - return fmt.Errorf("lecdn api error: code='%d', message='%s'", errcode, result.GetMessage()) - } - - return nil -} diff --git a/internal/pkg/sdk3rd/lecdn/v3/client/models.go b/internal/pkg/sdk3rd/lecdn/v3/client/models.go deleted file mode 100644 index 6d63ea79..00000000 --- a/internal/pkg/sdk3rd/lecdn/v3/client/models.go +++ /dev/null @@ -1,47 +0,0 @@ -package client - -type BaseResponse interface { - GetCode() int32 - GetMessage() string -} - -type baseResponse struct { - Code int32 `json:"code"` - Message string `json:"msg"` -} - -func (r *baseResponse) GetCode() int32 { - return r.Code -} - -func (r *baseResponse) GetMessage() string { - return r.Message -} - -type loginRequest struct { - Email string `json:"email"` - Username string `json:"username"` - Password string `json:"password"` -} - -type loginResponse struct { - baseResponse - Data *struct { - UserId int64 `json:"user_id"` - Username string `json:"username"` - Token string `json:"token"` - } `json:"data,omitempty"` -} - -type UpdateCertificateRequest struct { - Name string `json:"name"` - Description string `json:"description"` - Type string `json:"type"` - SSLPEM string `json:"ssl_pem"` - SSLKey string `json:"ssl_key"` - AutoRenewal bool `json:"auto_renewal"` -} - -type UpdateCertificateResponse struct { - baseResponse -} diff --git a/internal/pkg/sdk3rd/lecdn/v3/master/api.go b/internal/pkg/sdk3rd/lecdn/v3/master/api.go deleted file mode 100644 index 00f24a70..00000000 --- a/internal/pkg/sdk3rd/lecdn/v3/master/api.go +++ /dev/null @@ -1,49 +0,0 @@ -package master - -import ( - "encoding/json" - "fmt" - "net/http" -) - -func (c *Client) ensureAccessTokenExists() error { - c.accessTokenMtx.Lock() - defer c.accessTokenMtx.Unlock() - if c.accessToken != "" { - return nil - } - - req := &loginRequest{ - Username: c.username, - Password: c.password, - } - res, err := c.sendRequest(http.MethodPost, "/auth/login", req) - if err != nil { - return err - } - - resp := &loginResponse{} - if err := json.Unmarshal(res.Body(), &resp); err != nil { - return fmt.Errorf("lecdn api error: failed to unmarshal response: %w", err) - } else if resp.GetCode() != 200 { - return fmt.Errorf("lecdn get token failed: code='%d', message='%s'", resp.GetCode(), resp.GetMessage()) - } - - c.accessToken = resp.Data.Token - - return nil -} - -func (c *Client) UpdateCertificate(certId int64, req *UpdateCertificateRequest) (*UpdateCertificateResponse, error) { - if certId == 0 { - return nil, fmt.Errorf("lecdn api error: invalid parameter: CertId") - } - - if err := c.ensureAccessTokenExists(); err != nil { - return nil, err - } - - resp := &UpdateCertificateResponse{} - err := c.sendRequestWithResult(http.MethodPut, fmt.Sprintf("/certificate/%d", certId), req, resp) - return resp, err -} diff --git a/internal/pkg/sdk3rd/lecdn/v3/master/client.go b/internal/pkg/sdk3rd/lecdn/v3/master/client.go deleted file mode 100644 index dc033634..00000000 --- a/internal/pkg/sdk3rd/lecdn/v3/master/client.go +++ /dev/null @@ -1,100 +0,0 @@ -package master - -import ( - "crypto/tls" - "encoding/json" - "fmt" - "net/http" - "strings" - "sync" - "time" - - "github.com/go-resty/resty/v2" -) - -type Client struct { - username string - password string - - accessToken string - accessTokenMtx sync.Mutex - - client *resty.Client -} - -func NewClient(serverUrl, username, password string) *Client { - client := &Client{ - username: username, - password: password, - } - client.client = resty.New(). - SetBaseURL(strings.TrimRight(serverUrl, "/")+"/prod-api"). - SetHeader("User-Agent", "certimate"). - SetPreRequestHook(func(c *resty.Client, req *http.Request) error { - if client.accessToken != "" { - req.Header.Set("Authorization", "Bearer "+client.accessToken) - } - - return nil - }) - - return client -} - -func (c *Client) WithTimeout(timeout time.Duration) *Client { - c.client.SetTimeout(timeout) - return c -} - -func (c *Client) WithTLSConfig(config *tls.Config) *Client { - c.client.SetTLSClientConfig(config) - return c -} - -func (c *Client) sendRequest(method string, path string, params interface{}) (*resty.Response, error) { - req := c.client.R() - if strings.EqualFold(method, http.MethodGet) { - qs := make(map[string]string) - if params != nil { - temp := make(map[string]any) - jsonb, _ := json.Marshal(params) - json.Unmarshal(jsonb, &temp) - for k, v := range temp { - if v != nil { - qs[k] = fmt.Sprintf("%v", v) - } - } - } - - req = req.SetQueryParams(qs) - } else { - req = req.SetHeader("Content-Type", "application/json").SetBody(params) - } - - resp, err := req.Execute(method, path) - if err != nil { - return resp, fmt.Errorf("lecdn api error: failed to send request: %w", err) - } else if resp.IsError() { - return resp, fmt.Errorf("lecdn api error: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) - } - - return resp, nil -} - -func (c *Client) sendRequestWithResult(method string, path string, params interface{}, result BaseResponse) error { - resp, err := c.sendRequest(method, path, params) - if err != nil { - if resp != nil { - json.Unmarshal(resp.Body(), &result) - } - return err - } - - if err := json.Unmarshal(resp.Body(), &result); err != nil { - return fmt.Errorf("lecdn api error: failed to unmarshal response: %w", err) - } else if errcode := result.GetCode(); errcode != 200 { - return fmt.Errorf("lecdn api error: code='%d', message='%s'", errcode, result.GetMessage()) - } - - return nil -} diff --git a/internal/pkg/sdk3rd/lecdn/v3/master/models.go b/internal/pkg/sdk3rd/lecdn/v3/master/models.go deleted file mode 100644 index 2e896f42..00000000 --- a/internal/pkg/sdk3rd/lecdn/v3/master/models.go +++ /dev/null @@ -1,47 +0,0 @@ -package master - -type BaseResponse interface { - GetCode() int32 - GetMessage() string -} - -type baseResponse struct { - Code int32 `json:"code"` - Message string `json:"message"` -} - -func (r *baseResponse) GetCode() int32 { - return r.Code -} - -func (r *baseResponse) GetMessage() string { - return r.Message -} - -type loginRequest struct { - Username string `json:"username"` - Password string `json:"password"` -} - -type loginResponse struct { - baseResponse - Data *struct { - UserId int64 `json:"user_id"` - Username string `json:"username"` - Token string `json:"token"` - } `json:"data,omitempty"` -} - -type UpdateCertificateRequest struct { - ClientId int64 `json:"client_id"` - Name string `json:"name"` - Description string `json:"description"` - Type string `json:"type"` - SSLPEM string `json:"ssl_pem"` - SSLKey string `json:"ssl_key"` - AutoRenewal bool `json:"auto_renewal"` -} - -type UpdateCertificateResponse struct { - baseResponse -} diff --git a/internal/pkg/sdk3rd/netlify/api.go b/internal/pkg/sdk3rd/netlify/api.go deleted file mode 100644 index 095ff303..00000000 --- a/internal/pkg/sdk3rd/netlify/api.go +++ /dev/null @@ -1,17 +0,0 @@ -package netlify - -import ( - "fmt" - "net/http" - "net/url" -) - -func (c *Client) ProvisionSiteTLSCertificate(siteId string, params *ProvisionSiteTLSCertificateParams) (*ProvisionSiteTLSCertificateResponse, error) { - if siteId == "" { - return nil, fmt.Errorf("netlify api error: invalid parameter: SiteId") - } - - resp := &ProvisionSiteTLSCertificateResponse{} - err := c.sendRequestWithResult(http.MethodPost, fmt.Sprintf("/sites/%s/ssl", url.PathEscape(siteId)), params, nil, resp) - return resp, err -} diff --git a/internal/pkg/sdk3rd/netlify/api_provision_site_tls_certificate.go b/internal/pkg/sdk3rd/netlify/api_provision_site_tls_certificate.go new file mode 100644 index 00000000..6dc0e809 --- /dev/null +++ b/internal/pkg/sdk3rd/netlify/api_provision_site_tls_certificate.go @@ -0,0 +1,52 @@ +package netlify + +import ( + "context" + "fmt" + "net/http" + "net/url" +) + +type ProvisionSiteTLSCertificateParams struct { + Certificate string `json:"certificate"` + CACertificates string `json:"ca_certificates"` + Key string `json:"key"` +} + +type ProvisionSiteTLSCertificateResponse struct { + apiResponseBase + Domains []string `json:"domains,omitempty"` + State string `json:"state,omitempty"` + ExpiresAt string `json:"expires_at,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` +} + +func (c *Client) ProvisionSiteTLSCertificate(siteId string, req *ProvisionSiteTLSCertificateParams) (*ProvisionSiteTLSCertificateResponse, error) { + return c.ProvisionSiteTLSCertificateWithContext(context.Background(), siteId, req) +} + +func (c *Client) ProvisionSiteTLSCertificateWithContext(ctx context.Context, siteId string, req *ProvisionSiteTLSCertificateParams) (*ProvisionSiteTLSCertificateResponse, error) { + if siteId == "" { + return nil, fmt.Errorf("sdkerr: unset siteId") + } + + httpreq, err := c.newRequest(http.MethodPost, fmt.Sprintf("/sites/%s/ssl", url.PathEscape(siteId))) + if err != nil { + return nil, err + } else { + httpreq.SetQueryParams(map[string]string{ + "certificate": req.Certificate, + "ca_certificates": req.CACertificates, + "key": req.Key, + }) + httpreq.SetContext(ctx) + } + + result := &ProvisionSiteTLSCertificateResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/netlify/client.go b/internal/pkg/sdk3rd/netlify/client.go index bf3f4ad6..1a6fa908 100644 --- a/internal/pkg/sdk3rd/netlify/client.go +++ b/internal/pkg/sdk3rd/netlify/client.go @@ -3,8 +3,6 @@ package netlify import ( "encoding/json" "fmt" - "net/http" - "strings" "time" "github.com/go-resty/resty/v2" @@ -14,80 +12,80 @@ type Client struct { client *resty.Client } -func NewClient(apiToken string) *Client { +func NewClient(apiToken string) (*Client, error) { + if apiToken == "" { + return nil, fmt.Errorf("sdkerr: unset apiToken") + } + client := resty.New(). SetBaseURL("https://api.netlify.com/api/v1"). + SetHeader("Accept", "application/json"). SetHeader("Authorization", "Bearer "+apiToken). + SetHeader("Content-Type", "application/json"). SetHeader("User-Agent", "certimate") - return &Client{ - client: client, - } + return &Client{client}, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { +func (c *Client) SetTimeout(timeout time.Duration) *Client { c.client.SetTimeout(timeout) return c } -func (c *Client) sendRequest(method string, path string, queryParams interface{}, payloadParams interface{}) (*resty.Response, error) { +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") + } + req := c.client.R() + req.Method = method + req.URL = path + return req, nil +} - if queryParams != nil { - qs := make(map[string]string) - temp := make(map[string]any) - jsonb, _ := json.Marshal(queryParams) - json.Unmarshal(jsonb, &temp) - for k, v := range temp { - if v != nil { - qs[k] = fmt.Sprintf("%v", v) - } - } - req = req.SetQueryParams(qs) +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") } - if strings.EqualFold(method, http.MethodGet) { - qs := make(map[string]string) - if payloadParams != nil { - temp := make(map[string]any) - jsonb, _ := json.Marshal(payloadParams) - json.Unmarshal(jsonb, &temp) - for k, v := range temp { - if v != nil { - qs[k] = fmt.Sprintf("%v", v) - } - } - } + // WARN: + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. - req = req.SetQueryParams(qs) - } else { - req = req.SetHeader("Content-Type", "application/json").SetBody(payloadParams) - } - - resp, err := req.Execute(method, path) + resp, err := req.Send() if err != nil { - return resp, fmt.Errorf("netlify api error: failed to send request: %w", err) + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) } else if resp.IsError() { - return resp, fmt.Errorf("netlify api error: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) } return resp, nil } -func (c *Client) sendRequestWithResult(method string, path string, queryParams interface{}, payloadParams interface{}, result BaseResponse) error { - resp, err := c.sendRequest(method, path, queryParams, payloadParams) +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + resp, err := c.doRequest(req) if err != nil { if resp != nil { - json.Unmarshal(resp.Body(), &result) + json.Unmarshal(resp.Body(), &res) } - return err + return resp, err } - if err := json.Unmarshal(resp.Body(), &result); err != nil { - return fmt.Errorf("netlify api error: failed to unmarshal response: %w", err) - } else if errcode := result.GetCode(); errcode != 0 { - return fmt.Errorf("netlify api error: code='%d', message='%s'", errcode, result.GetMessage()) + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) + } else { + if tcode := res.GetCode(); tcode != 0 { + return resp, fmt.Errorf("sdkerr: code='%d', message='%s'", tcode, res.GetMessage()) + } + } } - return nil + return resp, nil } diff --git a/internal/pkg/sdk3rd/netlify/models.go b/internal/pkg/sdk3rd/netlify/models.go deleted file mode 100644 index 3ff2d216..00000000 --- a/internal/pkg/sdk3rd/netlify/models.go +++ /dev/null @@ -1,40 +0,0 @@ -package netlify - -type BaseResponse interface { - GetCode() int32 - GetMessage() string -} - -type baseResponse struct { - Code *int32 `json:"code,omitempty"` - Message *string `json:"message,omitempty"` -} - -func (r *baseResponse) GetCode() int32 { - if r.Code != nil { - return *r.Code - } - return 0 -} - -func (r *baseResponse) GetMessage() string { - if r.Message != nil { - return *r.Message - } - return "" -} - -type ProvisionSiteTLSCertificateParams struct { - Certificate string `json:"certificate"` - CACertificates string `json:"ca_certificates"` - Key string `json:"key"` -} - -type ProvisionSiteTLSCertificateResponse struct { - baseResponse - Domains []string `json:"domains,omitempty"` - State string `json:"state,omitempty"` - ExpiresAt string `json:"expires_at,omitempty"` - CreatedAt string `json:"created_at,omitempty"` - UpdatedAt string `json:"updated_at,omitempty"` -} diff --git a/internal/pkg/sdk3rd/netlify/types.go b/internal/pkg/sdk3rd/netlify/types.go new file mode 100644 index 00000000..301da2bf --- /dev/null +++ b/internal/pkg/sdk3rd/netlify/types.go @@ -0,0 +1,29 @@ +package netlify + +type apiResponse interface { + GetCode() int32 + GetMessage() string +} + +type apiResponseBase struct { + Code *int32 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` +} + +func (r *apiResponseBase) GetCode() int32 { + if r.Code == nil { + return 0 + } + + return *r.Code +} + +func (r *apiResponseBase) GetMessage() string { + if r.Message == nil { + return "" + } + + return *r.Message +} + +var _ apiResponse = (*apiResponseBase)(nil) diff --git a/internal/pkg/sdk3rd/qiniu/auth.go b/internal/pkg/sdk3rd/qiniu/auth.go index 6df13752..a1668dd7 100644 --- a/internal/pkg/sdk3rd/qiniu/auth.go +++ b/internal/pkg/sdk3rd/qiniu/auth.go @@ -4,6 +4,7 @@ import ( "net/http" "github.com/qiniu/go-sdk/v7/auth" + "github.com/qiniu/go-sdk/v7/client" ) type transport struct { @@ -13,7 +14,7 @@ type transport struct { func newTransport(mac *auth.Credentials, tr http.RoundTripper) *transport { if tr == nil { - tr = http.DefaultTransport + tr = client.DefaultTransport } return &transport{tr, mac} } diff --git a/internal/pkg/sdk3rd/qiniu/cdn.go b/internal/pkg/sdk3rd/qiniu/cdn.go new file mode 100644 index 00000000..54a56517 --- /dev/null +++ b/internal/pkg/sdk3rd/qiniu/cdn.go @@ -0,0 +1,134 @@ +package qiniu + +import ( + "context" + "fmt" + "net/http" + "strings" + + "github.com/qiniu/go-sdk/v7/auth" + "github.com/qiniu/go-sdk/v7/client" +) + +const qiniuHost = "https://api.qiniu.com" + +type CdnManager struct { + client *client.Client +} + +func NewCdnManager(mac *auth.Credentials) *CdnManager { + if mac == nil { + mac = auth.Default() + } + + client := &client.Client{&http.Client{Transport: newTransport(mac, nil)}} + return &CdnManager{client: client} +} + +func (m *CdnManager) urlf(pathf string, pathargs ...any) string { + path := fmt.Sprintf(pathf, pathargs...) + path = strings.TrimPrefix(path, "/") + return qiniuHost + "/" + path +} + +type GetDomainInfoResponse struct { + Code *int `json:"code,omitempty"` + Error *string `json:"error,omitempty"` + Name string `json:"name"` + Type string `json:"type"` + CName string `json:"cname"` + Https *struct { + CertID string `json:"certId"` + ForceHttps bool `json:"forceHttps"` + Http2Enable bool `json:"http2Enable"` + } `json:"https"` + PareDomain string `json:"pareDomain"` + OperationType string `json:"operationType"` + OperatingState string `json:"operatingState"` + OperatingStateDesc string `json:"operatingStateDesc"` + CreateAt string `json:"createAt"` + ModifyAt string `json:"modifyAt"` +} + +func (m *CdnManager) GetDomainInfo(ctx context.Context, domain string) (*GetDomainInfoResponse, error) { + resp := new(GetDomainInfoResponse) + if err := m.client.Call(ctx, resp, http.MethodGet, m.urlf("domain/%s", domain), nil); err != nil { + return nil, err + } + return resp, nil +} + +type ModifyDomainHttpsConfRequest struct { + CertID string `json:"certId"` + ForceHttps bool `json:"forceHttps"` + Http2Enable bool `json:"http2Enable"` +} + +type ModifyDomainHttpsConfResponse struct { + Code *int `json:"code,omitempty"` + Error *string `json:"error,omitempty"` +} + +func (m *CdnManager) ModifyDomainHttpsConf(ctx context.Context, domain string, certId string, forceHttps bool, http2Enable bool) (*ModifyDomainHttpsConfResponse, error) { + req := &ModifyDomainHttpsConfRequest{ + CertID: certId, + ForceHttps: forceHttps, + Http2Enable: http2Enable, + } + resp := new(ModifyDomainHttpsConfResponse) + if err := m.client.CallWithJson(ctx, resp, http.MethodPut, m.urlf("domain/%s/httpsconf", domain), nil, req); err != nil { + return nil, err + } + return resp, nil +} + +type EnableDomainHttpsRequest struct { + CertID string `json:"certId"` + ForceHttps bool `json:"forceHttps"` + Http2Enable bool `json:"http2Enable"` +} + +type EnableDomainHttpsResponse struct { + Code *int `json:"code,omitempty"` + Error *string `json:"error,omitempty"` +} + +func (m *CdnManager) EnableDomainHttps(ctx context.Context, domain string, certId string, forceHttps bool, http2Enable bool) (*EnableDomainHttpsResponse, error) { + req := &EnableDomainHttpsRequest{ + CertID: certId, + ForceHttps: forceHttps, + Http2Enable: http2Enable, + } + resp := new(EnableDomainHttpsResponse) + if err := m.client.CallWithJson(ctx, resp, http.MethodPut, m.urlf("domain/%s/sslize", domain), nil, req); err != nil { + return nil, err + } + return resp, nil +} + +type UploadSslCertRequest struct { + Name string `json:"name"` + CommonName string `json:"common_name"` + Certificate string `json:"ca"` + PrivateKey string `json:"pri"` +} + +type UploadSslCertResponse struct { + Code *int `json:"code,omitempty"` + Error *string `json:"error,omitempty"` + CertID string `json:"certID"` +} + +func (m *CdnManager) UploadSslCert(ctx context.Context, name string, commonName string, certificate string, privateKey string) (*UploadSslCertResponse, error) { + req := &UploadSslCertRequest{ + Name: name, + CommonName: commonName, + Certificate: certificate, + PrivateKey: privateKey, + } + resp := new(UploadSslCertResponse) + if err := m.client.CallWithJson(ctx, resp, http.MethodPost, m.urlf("sslcert"), nil, req); err != nil { + return nil, err + } + return resp, nil +} diff --git a/internal/pkg/sdk3rd/qiniu/client.go b/internal/pkg/sdk3rd/qiniu/client.go deleted file mode 100644 index 0d777aa3..00000000 --- a/internal/pkg/sdk3rd/qiniu/client.go +++ /dev/null @@ -1,85 +0,0 @@ -package qiniu - -import ( - "context" - "fmt" - "net/http" - "strings" - - "github.com/qiniu/go-sdk/v7/auth" - "github.com/qiniu/go-sdk/v7/client" -) - -const qiniuHost = "https://api.qiniu.com" - -type Client struct { - client *client.Client -} - -func NewClient(mac *auth.Credentials) *Client { - if mac == nil { - mac = auth.Default() - } - - client := client.DefaultClient - client.Transport = newTransport(mac, nil) - return &Client{client: &client} -} - -func (c *Client) GetDomainInfo(ctx context.Context, domain string) (*GetDomainInfoResponse, error) { - resp := new(GetDomainInfoResponse) - if err := c.client.Call(ctx, resp, http.MethodGet, c.urlf("domain/%s", domain), nil); err != nil { - return nil, err - } - return resp, nil -} - -func (c *Client) ModifyDomainHttpsConf(ctx context.Context, domain string, certId string, forceHttps bool, http2Enable bool) (*ModifyDomainHttpsConfResponse, error) { - req := &ModifyDomainHttpsConfRequest{ - DomainInfoHttpsData: DomainInfoHttpsData{ - CertID: certId, - ForceHttps: forceHttps, - Http2Enable: http2Enable, - }, - } - resp := new(ModifyDomainHttpsConfResponse) - if err := c.client.CallWithJson(ctx, resp, http.MethodPut, c.urlf("domain/%s/httpsconf", domain), nil, req); err != nil { - return nil, err - } - return resp, nil -} - -func (c *Client) EnableDomainHttps(ctx context.Context, domain string, certId string, forceHttps bool, http2Enable bool) (*EnableDomainHttpsResponse, error) { - req := &EnableDomainHttpsRequest{ - DomainInfoHttpsData: DomainInfoHttpsData{ - CertID: certId, - ForceHttps: forceHttps, - Http2Enable: http2Enable, - }, - } - resp := new(EnableDomainHttpsResponse) - if err := c.client.CallWithJson(ctx, resp, http.MethodPut, c.urlf("domain/%s/sslize", domain), nil, req); err != nil { - return nil, err - } - return resp, nil -} - -func (c *Client) UploadSslCert(ctx context.Context, name string, commonName string, certificate string, privateKey string) (*UploadSslCertResponse, error) { - req := &UploadSslCertRequest{ - Name: name, - CommonName: commonName, - Certificate: certificate, - PrivateKey: privateKey, - } - resp := new(UploadSslCertResponse) - if err := c.client.CallWithJson(ctx, resp, http.MethodPost, c.urlf("sslcert"), nil, req); err != nil { - return nil, err - } - return resp, nil -} - -func (c *Client) urlf(pathf string, pathargs ...any) string { - path := fmt.Sprintf(pathf, pathargs...) - path = strings.TrimPrefix(path, "/") - return qiniuHost + "/" + path -} diff --git a/internal/pkg/sdk3rd/qiniu/models.go b/internal/pkg/sdk3rd/qiniu/models.go deleted file mode 100644 index 1c832caf..00000000 --- a/internal/pkg/sdk3rd/qiniu/models.go +++ /dev/null @@ -1,54 +0,0 @@ -package qiniu - -type BaseResponse struct { - Code *int `json:"code,omitempty"` - Error *string `json:"error,omitempty"` -} - -type UploadSslCertRequest struct { - Name string `json:"name"` - CommonName string `json:"common_name"` - Certificate string `json:"ca"` - PrivateKey string `json:"pri"` -} - -type UploadSslCertResponse struct { - BaseResponse - CertID string `json:"certID"` -} - -type DomainInfoHttpsData struct { - CertID string `json:"certId"` - ForceHttps bool `json:"forceHttps"` - Http2Enable bool `json:"http2Enable"` -} - -type GetDomainInfoResponse struct { - BaseResponse - Name string `json:"name"` - Type string `json:"type"` - CName string `json:"cname"` - Https *DomainInfoHttpsData `json:"https"` - PareDomain string `json:"pareDomain"` - OperationType string `json:"operationType"` - OperatingState string `json:"operatingState"` - OperatingStateDesc string `json:"operatingStateDesc"` - CreateAt string `json:"createAt"` - ModifyAt string `json:"modifyAt"` -} - -type ModifyDomainHttpsConfRequest struct { - DomainInfoHttpsData -} - -type ModifyDomainHttpsConfResponse struct { - BaseResponse -} - -type EnableDomainHttpsRequest struct { - DomainInfoHttpsData -} - -type EnableDomainHttpsResponse struct { - BaseResponse -} diff --git a/internal/pkg/sdk3rd/rainyun/api.go b/internal/pkg/sdk3rd/rainyun/api.go deleted file mode 100644 index cdb0eccb..00000000 --- a/internal/pkg/sdk3rd/rainyun/api.go +++ /dev/null @@ -1,38 +0,0 @@ -package rainyun - -import ( - "fmt" - "net/http" -) - -func (c *Client) SslCenterList(req *SslCenterListRequest) (*SslCenterListResponse, error) { - resp := &SslCenterListResponse{} - err := c.sendRequestWithResult(http.MethodGet, "/product/sslcenter", req, resp) - return resp, err -} - -func (c *Client) SslCenterGet(id int32) (*SslCenterGetResponse, error) { - if id == 0 { - return nil, fmt.Errorf("rainyun api error: invalid parameter: id") - } - - resp := &SslCenterGetResponse{} - err := c.sendRequestWithResult(http.MethodGet, fmt.Sprintf("/product/sslcenter/%d", id), nil, resp) - return resp, err -} - -func (c *Client) SslCenterCreate(req *SslCenterCreateRequest) (*SslCenterCreateResponse, error) { - resp := &SslCenterCreateResponse{} - err := c.sendRequestWithResult(http.MethodPost, "/product/sslcenter/", req, resp) - return resp, err -} - -func (c *Client) RcdnInstanceSslBind(id int32, req *RcdnInstanceSslBindRequest) (*RcdnInstanceSslBindResponse, error) { - if id == 0 { - return nil, fmt.Errorf("rainyun api error: invalid parameter: id") - } - - resp := &RcdnInstanceSslBindResponse{} - err := c.sendRequestWithResult(http.MethodPost, fmt.Sprintf("/product/rcdn/instance/%d/ssl_bind", id), req, resp) - return resp, err -} diff --git a/internal/pkg/sdk3rd/rainyun/api_rcdn_instance_ssl_bind.go b/internal/pkg/sdk3rd/rainyun/api_rcdn_instance_ssl_bind.go new file mode 100644 index 00000000..4790be12 --- /dev/null +++ b/internal/pkg/sdk3rd/rainyun/api_rcdn_instance_ssl_bind.go @@ -0,0 +1,41 @@ +package rainyun + +import ( + "context" + "fmt" + "net/http" +) + +type RcdnInstanceSslBindRequest struct { + CertId int32 `json:"cert_id"` + Domains []string `json:"domains"` +} + +type RcdnInstanceSslBindResponse struct { + apiResponseBase +} + +func (c *Client) RcdnInstanceSslBind(instanceId int32, req *RcdnInstanceSslBindRequest) (*RcdnInstanceSslBindResponse, error) { + return c.RcdnInstanceSslBindWithContext(context.Background(), instanceId, req) +} + +func (c *Client) RcdnInstanceSslBindWithContext(ctx context.Context, instanceId int32, req *RcdnInstanceSslBindRequest) (*RcdnInstanceSslBindResponse, error) { + if instanceId == 0 { + return nil, fmt.Errorf("sdkerr: unset instanceId") + } + + httpreq, err := c.newRequest(http.MethodPost, fmt.Sprintf("/product/rcdn/instance/%d/ssl_bind", instanceId)) + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &RcdnInstanceSslBindResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/rainyun/api_ssl_center_create.go b/internal/pkg/sdk3rd/rainyun/api_ssl_center_create.go new file mode 100644 index 00000000..1af08e5b --- /dev/null +++ b/internal/pkg/sdk3rd/rainyun/api_ssl_center_create.go @@ -0,0 +1,36 @@ +package rainyun + +import ( + "context" + "net/http" +) + +type SslCenterCreateRequest struct { + Cert string `json:"cert"` + Key string `json:"key"` +} + +type SslCenterCreateResponse struct { + apiResponseBase +} + +func (c *Client) SslCenterCreate(req *SslCenterCreateRequest) (*SslCenterCreateResponse, error) { + return c.SslCenterCreateWithContext(context.Background(), req) +} + +func (c *Client) SslCenterCreateWithContext(ctx context.Context, req *SslCenterCreateRequest) (*SslCenterCreateResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/product/sslcenter/") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &SslCenterCreateResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/rainyun/api_ssl_center_get.go b/internal/pkg/sdk3rd/rainyun/api_ssl_center_get.go new file mode 100644 index 00000000..6dec58ce --- /dev/null +++ b/internal/pkg/sdk3rd/rainyun/api_ssl_center_get.go @@ -0,0 +1,37 @@ +package rainyun + +import ( + "context" + "fmt" + "net/http" +) + +type SslCenterGetResponse struct { + apiResponseBase + + Data *SslDetail `json:"data,omitempty"` +} + +func (c *Client) SslCenterGet(sslId int32) (*SslCenterGetResponse, error) { + return c.SslCenterGetWithContext(context.Background(), sslId) +} + +func (c *Client) SslCenterGetWithContext(ctx context.Context, sslId int32) (*SslCenterGetResponse, error) { + if sslId == 0 { + return nil, fmt.Errorf("sdkerr: unset sslId") + } + + httpreq, err := c.newRequest(http.MethodGet, fmt.Sprintf("/product/sslcenter/%d", sslId)) + if err != nil { + return nil, err + } else { + httpreq.SetContext(ctx) + } + + result := &SslCenterGetResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/rainyun/api_ssl_center_list.go b/internal/pkg/sdk3rd/rainyun/api_ssl_center_list.go new file mode 100644 index 00000000..e727c3b0 --- /dev/null +++ b/internal/pkg/sdk3rd/rainyun/api_ssl_center_list.go @@ -0,0 +1,49 @@ +package rainyun + +import ( + "context" + "encoding/json" + "net/http" +) + +type SslCenterListFilters struct { + Domain *string `json:"Domain,omitempty"` +} + +type SslCenterListRequest struct { + Filters *SslCenterListFilters `json:"columnFilters,omitempty"` + Sort []*string `json:"sort,omitempty"` + Page *int32 `json:"page,omitempty"` + PerPage *int32 `json:"perPage,omitempty"` +} + +type SslCenterListResponse struct { + apiResponseBase + + Data *struct { + TotalRecords int32 `json:"TotalRecords"` + Records []*SslRecord `json:"Records"` + } `json:"data,omitempty"` +} + +func (c *Client) SslCenterList(req *SslCenterListRequest) (*SslCenterListResponse, error) { + return c.SslCenterListWithContext(context.Background(), req) +} + +func (c *Client) SslCenterListWithContext(ctx context.Context, req *SslCenterListRequest) (*SslCenterListResponse, error) { + httpreq, err := c.newRequest(http.MethodGet, "/product/sslcenter") + if err != nil { + return nil, err + } else { + jsonb, _ := json.Marshal(req) + httpreq.SetQueryParam("options", string(jsonb)) + httpreq.SetContext(ctx) + } + + result := &SslCenterListResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/rainyun/client.go b/internal/pkg/sdk3rd/rainyun/client.go index cf9e1895..e7f2fb5a 100644 --- a/internal/pkg/sdk3rd/rainyun/client.go +++ b/internal/pkg/sdk3rd/rainyun/client.go @@ -3,8 +3,6 @@ package rainyun import ( "encoding/json" "fmt" - "net/http" - "strings" "time" "github.com/go-resty/resty/v2" @@ -14,57 +12,80 @@ type Client struct { client *resty.Client } -func NewClient(apiKey string) *Client { +func NewClient(apiKey string) (*Client, error) { + if apiKey == "" { + return nil, fmt.Errorf("sdkerr: unset apiKey") + } + client := resty.New(). SetBaseURL("https://api.v2.rainyun.com"). + SetHeader("Accept", "application/json"). + SetHeader("Content-Type", "application/json"). SetHeader("User-Agent", "certimate"). SetHeader("X-API-Key", apiKey) - return &Client{ - client: client, - } + return &Client{client}, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { +func (c *Client) SetTimeout(timeout time.Duration) *Client { c.client.SetTimeout(timeout) return c } -func (c *Client) sendRequest(method string, path string, params interface{}) (*resty.Response, error) { - req := c.client.R() - if strings.EqualFold(method, http.MethodGet) { - if params != nil { - jsonb, _ := json.Marshal(params) - req = req.SetQueryParam("options", string(jsonb)) - } - } else { - req = req.SetHeader("Content-Type", "application/json").SetBody(params) +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") } - resp, err := req.Execute(method, path) + req := c.client.R() + req.Method = method + req.URL = path + return req, nil +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + // WARN: + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. + + resp, err := req.Send() if err != nil { - return resp, fmt.Errorf("rainyun api error: failed to send request: %w", err) + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) } else if resp.IsError() { - return resp, fmt.Errorf("rainyun api error: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) } return resp, nil } -func (c *Client) sendRequestWithResult(method string, path string, params interface{}, result BaseResponse) error { - resp, err := c.sendRequest(method, path, params) +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + resp, err := c.doRequest(req) if err != nil { if resp != nil { - json.Unmarshal(resp.Body(), &result) + json.Unmarshal(resp.Body(), &res) } - return err + return resp, err } - if err := json.Unmarshal(resp.Body(), &result); err != nil { - return fmt.Errorf("rainyun api error: failed to unmarshal response: %w", err) - } else if errcode := result.GetCode(); errcode/100 != 2 { - return fmt.Errorf("rainyun api error: code='%d', message='%s'", errcode, result.GetMessage()) + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) + } else { + if tcode := res.GetCode(); tcode/100 != 2 { + return resp, fmt.Errorf("sdkerr: code='%d', message='%s'", tcode, res.GetMessage()) + } + } } - return nil + return resp, nil } diff --git a/internal/pkg/sdk3rd/rainyun/models.go b/internal/pkg/sdk3rd/rainyun/models.go deleted file mode 100644 index e6ef4671..00000000 --- a/internal/pkg/sdk3rd/rainyun/models.go +++ /dev/null @@ -1,83 +0,0 @@ -package rainyun - -type BaseResponse interface { - GetCode() int32 - GetMessage() string -} - -type baseResponse struct { - Code *int32 `json:"code,omitempty"` - Message *string `json:"message,omitempty"` -} - -func (r *baseResponse) GetCode() int32 { - if r.Code != nil { - return *r.Code - } - return 0 -} - -func (r *baseResponse) GetMessage() string { - if r.Message != nil { - return *r.Message - } - return "" -} - -type SslCenterListFilters struct { - Domain *string `json:"Domain,omitempty"` -} - -type SslCenterListRequest struct { - Filters *SslCenterListFilters `json:"columnFilters,omitempty"` - Sort []*string `json:"sort,omitempty"` - Page *int32 `json:"page,omitempty"` - PerPage *int32 `json:"perPage,omitempty"` -} - -type SslCenterListResponse struct { - baseResponse - Data *struct { - TotalRecords int32 `json:"TotalRecords"` - Records []*struct { - ID int32 `json:"ID"` - UID int32 `json:"UID"` - Domain string `json:"Domain"` - Issuer string `json:"Issuer"` - StartDate int64 `json:"StartDate"` - ExpireDate int64 `json:"ExpDate"` - UploadTime int64 `json:"UploadTime"` - } `json:"Records"` - } `json:"data,omitempty"` -} - -type SslCenterGetResponse struct { - baseResponse - Data *struct { - Cert string `json:"Cert"` - Key string `json:"Key"` - Domain string `json:"DomainName"` - Issuer string `json:"Issuer"` - StartDate int64 `json:"StartDate"` - ExpireDate int64 `json:"ExpDate"` - RemainDays int32 `json:"RemainDays"` - } `json:"data,omitempty"` -} - -type SslCenterCreateRequest struct { - Cert string `json:"cert"` - Key string `json:"key"` -} - -type SslCenterCreateResponse struct { - baseResponse -} - -type RcdnInstanceSslBindRequest struct { - CertId int32 `json:"cert_id"` - Domains []string `json:"domains"` -} - -type RcdnInstanceSslBindResponse struct { - baseResponse -} diff --git a/internal/pkg/sdk3rd/rainyun/types.go b/internal/pkg/sdk3rd/rainyun/types.go new file mode 100644 index 00000000..47937f71 --- /dev/null +++ b/internal/pkg/sdk3rd/rainyun/types.go @@ -0,0 +1,49 @@ +package rainyun + +type apiResponse interface { + GetCode() int32 + GetMessage() string +} + +type apiResponseBase struct { + Code *int32 `json:"code,omitempty"` + Message *string `json:"message,omitempty"` +} + +func (r *apiResponseBase) GetCode() int32 { + if r.Code == nil { + return 0 + } + + return *r.Code +} + +func (r *apiResponseBase) GetMessage() string { + if r.Message == nil { + return "" + } + + return *r.Message +} + +var _ apiResponse = (*apiResponseBase)(nil) + +type SslRecord struct { + ID int32 `json:"ID"` + UID int32 `json:"UID"` + Domain string `json:"Domain"` + Issuer string `json:"Issuer"` + StartDate int64 `json:"StartDate"` + ExpireDate int64 `json:"ExpDate"` + UploadTime int64 `json:"UploadTime"` +} + +type SslDetail struct { + Cert string `json:"Cert"` + Key string `json:"Key"` + Domain string `json:"DomainName"` + Issuer string `json:"Issuer"` + StartDate int64 `json:"StartDate"` + ExpireDate int64 `json:"ExpDate"` + RemainDays int32 `json:"RemainDays"` +} diff --git a/internal/pkg/sdk3rd/ratpanel/api.go b/internal/pkg/sdk3rd/ratpanel/api.go deleted file mode 100644 index 17f8110f..00000000 --- a/internal/pkg/sdk3rd/ratpanel/api.go +++ /dev/null @@ -1,15 +0,0 @@ -package ratpanelsdk - -import "net/http" - -func (c *Client) SettingCert(req *SettingCertRequest) (*SettingCertResponse, error) { - resp := &SettingCertResponse{} - err := c.sendRequestWithResult(http.MethodPost, "/setting/cert", req, resp) - return resp, err -} - -func (c *Client) WebsiteCert(req *WebsiteCertRequest) (*WebsiteCertResponse, error) { - resp := &WebsiteCertResponse{} - err := c.sendRequestWithResult(http.MethodPost, "/website/cert", req, resp) - return resp, err -} diff --git a/internal/pkg/sdk3rd/ratpanel/api_set_setting_cert.go b/internal/pkg/sdk3rd/ratpanel/api_set_setting_cert.go new file mode 100644 index 00000000..7a026b48 --- /dev/null +++ b/internal/pkg/sdk3rd/ratpanel/api_set_setting_cert.go @@ -0,0 +1,36 @@ +package ratpanel + +import ( + "context" + "net/http" +) + +type SetSettingCertRequest struct { + Certificate string `json:"cert"` + PrivateKey string `json:"key"` +} + +type SetSettingCertResponse struct { + apiResponseBase +} + +func (c *Client) SetSettingCert(req *SetSettingCertRequest) (*SetSettingCertResponse, error) { + return c.SetSettingCertWithContext(context.Background(), req) +} + +func (c *Client) SetSettingCertWithContext(ctx context.Context, req *SetSettingCertRequest) (*SetSettingCertResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/setting/cert") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &SetSettingCertResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/ratpanel/api_set_website_cert.go b/internal/pkg/sdk3rd/ratpanel/api_set_website_cert.go new file mode 100644 index 00000000..679373fa --- /dev/null +++ b/internal/pkg/sdk3rd/ratpanel/api_set_website_cert.go @@ -0,0 +1,37 @@ +package ratpanel + +import ( + "context" + "net/http" +) + +type SetWebsiteCertRequest struct { + SiteName string `json:"name"` + Certificate string `json:"cert"` + PrivateKey string `json:"key"` +} + +type SetWebsiteCertResponse struct { + apiResponseBase +} + +func (c *Client) SetWebsiteCert(req *SetWebsiteCertRequest) (*SetWebsiteCertResponse, error) { + return c.SetWebsiteCertWithContext(context.Background(), req) +} + +func (c *Client) SetWebsiteCertWithContext(ctx context.Context, req *SetWebsiteCertRequest) (*SetWebsiteCertResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/website/cert") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &SetWebsiteCertResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/ratpanel/client.go b/internal/pkg/sdk3rd/ratpanel/client.go index e1abb6c5..155e2349 100644 --- a/internal/pkg/sdk3rd/ratpanel/client.go +++ b/internal/pkg/sdk3rd/ratpanel/client.go @@ -1,4 +1,4 @@ -package ratpanelsdk +package ratpanel import ( "bytes" @@ -10,6 +10,7 @@ import ( "fmt" "io" "net/http" + "net/url" "strings" "time" @@ -20,7 +21,20 @@ type Client struct { client *resty.Client } -func NewClient(serverUrl string, accessTokenId int32, accessToken string) *Client { +func NewClient(serverUrl string, accessTokenId int32, accessToken string) (*Client, error) { + if serverUrl == "" { + return nil, fmt.Errorf("sdkerr: unset serverUrl") + } + if _, err := url.Parse(serverUrl); err != nil { + return nil, fmt.Errorf("sdkerr: invalid serverUrl: %w", err) + } + if accessTokenId == 0 { + return nil, fmt.Errorf("sdkerr: unset accessTokenId") + } + if accessToken == "" { + return nil, fmt.Errorf("sdkerr: unset accessToken") + } + client := resty.New(). SetBaseURL(strings.TrimRight(serverUrl, "/")+"/api"). SetHeader("Accept", "application/json"). @@ -50,7 +64,7 @@ func NewClient(serverUrl string, accessTokenId int32, accessToken string) *Clien req.Method, canonicalPath, req.URL.Query().Encode(), - sha256Sum(string(body))) + sumSha256(string(body))) timestamp := time.Now().Unix() req.Header.Set("X-Timestamp", fmt.Sprintf("%d", timestamp)) @@ -58,84 +72,92 @@ func NewClient(serverUrl string, accessTokenId int32, accessToken string) *Clien stringToSign := fmt.Sprintf("%s\n%d\n%s", "HMAC-SHA256", timestamp, - sha256Sum(canonicalRequest)) - signature := hmacSha256(stringToSign, accessToken) + sumSha256(canonicalRequest)) + signature := sumHmacSha256(stringToSign, accessToken) req.Header.Set("Authorization", fmt.Sprintf("HMAC-SHA256 Credential=%d, Signature=%s", accessTokenId, signature)) return nil }) - return &Client{ - client: client, - } + return &Client{client}, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { +func (c *Client) SetTimeout(timeout time.Duration) *Client { c.client.SetTimeout(timeout) return c } -func (c *Client) WithTLSConfig(config *tls.Config) *Client { +func (c *Client) SetTLSConfig(config *tls.Config) *Client { c.client.SetTLSClientConfig(config) return c } -func (c *Client) sendRequest(method string, path string, params interface{}) (*resty.Response, error) { - req := c.client.R() - if strings.EqualFold(method, http.MethodGet) { - qs := make(map[string]string) - if params != nil { - temp := make(map[string]any) - jsonb, _ := json.Marshal(params) - json.Unmarshal(jsonb, &temp) - for k, v := range temp { - if v != nil { - qs[k] = fmt.Sprintf("%v", v) - } - } - } - - req = req.SetQueryParams(qs) - } else { - req = req.SetHeader("Content-Type", "application/json").SetBody(params) +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") } - resp, err := req.Execute(method, path) + req := c.client.R() + req.Method = method + req.URL = path + return req, nil +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + // WARN: + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. + + resp, err := req.Send() if err != nil { - return resp, fmt.Errorf("ratpanel api error: failed to send request: %w", err) + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) } else if resp.IsError() { - return resp, fmt.Errorf("ratpanel api error: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.Body()) + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) } return resp, nil } -func (c *Client) sendRequestWithResult(method string, path string, params interface{}, result BaseResponse) error { - resp, err := c.sendRequest(method, path, params) +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + resp, err := c.doRequest(req) if err != nil { if resp != nil { - json.Unmarshal(resp.Body(), &result) + json.Unmarshal(resp.Body(), &res) } - return err + return resp, err } - if err = json.Unmarshal(resp.Body(), &result); err != nil { - return fmt.Errorf("ratpanel api error: failed to unmarshal response: %w", err) - } else if errmsg := result.GetMessage(); errmsg != "success" { - return fmt.Errorf("ratpanel api error: message='%s'", errmsg) + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) + } else { + if tmessage := res.GetMessage(); tmessage != "success" { + return resp, fmt.Errorf("sdkerr: message='%s'", tmessage) + } + } } - return nil + return resp, nil } -func sha256Sum(str string) string { +func sumSha256(str string) string { sum := sha256.Sum256([]byte(str)) dst := make([]byte, hex.EncodedLen(len(sum))) hex.Encode(dst, sum[:]) return string(dst) } -func hmacSha256(data string, secret string) string { +func sumHmacSha256(data string, secret string) string { h := hmac.New(sha256.New, []byte(secret)) h.Write([]byte(data)) return hex.EncodeToString(h.Sum(nil)) diff --git a/internal/pkg/sdk3rd/ratpanel/models.go b/internal/pkg/sdk3rd/ratpanel/models.go deleted file mode 100644 index bf5f53fb..00000000 --- a/internal/pkg/sdk3rd/ratpanel/models.go +++ /dev/null @@ -1,35 +0,0 @@ -package ratpanelsdk - -type BaseResponse interface { - GetMessage() string -} - -type baseResponse struct { - Message *string `json:"msg,omitempty"` -} - -func (r *baseResponse) GetMessage() string { - if r.Message != nil { - return *r.Message - } - return "" -} - -type SettingCertRequest struct { - Certificate string `json:"cert"` - PrivateKey string `json:"key"` -} - -type SettingCertResponse struct { - baseResponse -} - -type WebsiteCertRequest struct { - SiteName string `json:"name"` - Certificate string `json:"cert"` - PrivateKey string `json:"key"` -} - -type WebsiteCertResponse struct { - baseResponse -} diff --git a/internal/pkg/sdk3rd/ratpanel/types.go b/internal/pkg/sdk3rd/ratpanel/types.go new file mode 100644 index 00000000..16a17b0e --- /dev/null +++ b/internal/pkg/sdk3rd/ratpanel/types.go @@ -0,0 +1,19 @@ +package ratpanel + +type apiResponse interface { + GetMessage() string +} + +type apiResponseBase struct { + Message *string `json:"msg,omitempty"` +} + +func (r *apiResponseBase) GetMessage() string { + if r.Message == nil { + return "" + } + + return *r.Message +} + +var _ apiResponse = (*apiResponseBase)(nil) diff --git a/internal/pkg/sdk3rd/safeline/api.go b/internal/pkg/sdk3rd/safeline/api.go deleted file mode 100644 index 52024370..00000000 --- a/internal/pkg/sdk3rd/safeline/api.go +++ /dev/null @@ -1,7 +0,0 @@ -package safeline - -func (c *Client) UpdateCertificate(req *UpdateCertificateRequest) (*UpdateCertificateResponse, error) { - resp := &UpdateCertificateResponse{} - err := c.sendRequestWithResult("/api/open/cert", req, resp) - return resp, err -} diff --git a/internal/pkg/sdk3rd/safeline/api_update_certificate.go b/internal/pkg/sdk3rd/safeline/api_update_certificate.go new file mode 100644 index 00000000..3dcbb5ba --- /dev/null +++ b/internal/pkg/sdk3rd/safeline/api_update_certificate.go @@ -0,0 +1,37 @@ +package safeline + +import ( + "context" + "net/http" +) + +type UpdateCertificateRequest struct { + Id int32 `json:"id"` + Type int32 `json:"type"` + Manual *CertificateManul `json:"manual"` +} + +type UpdateCertificateResponse struct { + apiResponseBase +} + +func (c *Client) UpdateCertificate(req *UpdateCertificateRequest) (*UpdateCertificateResponse, error) { + return c.UpdateCertificateWithContext(context.Background(), req) +} + +func (c *Client) UpdateCertificateWithContext(ctx context.Context, req *UpdateCertificateRequest) (*UpdateCertificateResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/api/open/cert") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &UpdateCertificateResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/safeline/client.go b/internal/pkg/sdk3rd/safeline/client.go index 05ee6d1a..5d7ee668 100644 --- a/internal/pkg/sdk3rd/safeline/client.go +++ b/internal/pkg/sdk3rd/safeline/client.go @@ -4,6 +4,7 @@ import ( "crypto/tls" "encoding/json" "fmt" + "net/url" "strings" "time" @@ -14,58 +15,91 @@ type Client struct { client *resty.Client } -func NewClient(serverUrl, apiToken string) *Client { +func NewClient(serverUrl, apiToken string) (*Client, error) { + if serverUrl == "" { + return nil, fmt.Errorf("sdkerr: unset serverUrl") + } + if _, err := url.Parse(serverUrl); err != nil { + return nil, fmt.Errorf("sdkerr: invalid serverUrl: %w", err) + } + if apiToken == "" { + return nil, fmt.Errorf("sdkerr: unset apiToken") + } + client := resty.New(). SetBaseURL(strings.TrimRight(serverUrl, "/")). + SetHeader("Accept", "application/json"). SetHeader("Content-Type", "application/json"). SetHeader("User-Agent", "certimate"). SetHeader("X-SLCE-API-TOKEN", apiToken) - return &Client{ - client: client, - } + return &Client{client}, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { +func (c *Client) SetTimeout(timeout time.Duration) *Client { c.client.SetTimeout(timeout) return c } -func (c *Client) WithTLSConfig(config *tls.Config) *Client { +func (c *Client) SetTLSConfig(config *tls.Config) *Client { c.client.SetTLSClientConfig(config) return c } -func (c *Client) sendRequest(path string, params interface{}) (*resty.Response, error) { - req := c.client.R().SetBody(params) - resp, err := req.Post(path) +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") + } + + req := c.client.R() + req.Method = method + req.URL = path + return req, nil +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + // WARN: + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. + + resp, err := req.Send() if err != nil { - return resp, fmt.Errorf("safeline api error: failed to send request: %w", err) + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) } else if resp.IsError() { - return resp, fmt.Errorf("safeline api error: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) } return resp, nil } -func (c *Client) sendRequestWithResult(path string, params interface{}, result BaseResponse) error { - resp, err := c.sendRequest(path, params) +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + resp, err := c.doRequest(req) if err != nil { if resp != nil { - json.Unmarshal(resp.Body(), &result) + json.Unmarshal(resp.Body(), &res) } - return err + return resp, err } - if err := json.Unmarshal(resp.Body(), &result); err != nil { - return fmt.Errorf("safeline api error: failed to unmarshal response: %w", err) - } else if errcode := result.GetErrCode(); errcode != nil && *errcode != "" { - if result.GetErrMsg() == nil { - return fmt.Errorf("safeline api error: code='%s'", *errcode) + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) } else { - return fmt.Errorf("safeline api error: code='%s', message='%s'", *errcode, *result.GetErrMsg()) + if terrcode := res.GetErrCode(); terrcode != "" { + return resp, fmt.Errorf("sdkerr: err='%s', msg='%s'", terrcode, res.GetErrMsg()) + } } } - return nil + return resp, nil } diff --git a/internal/pkg/sdk3rd/safeline/models.go b/internal/pkg/sdk3rd/safeline/models.go deleted file mode 100644 index f37b4348..00000000 --- a/internal/pkg/sdk3rd/safeline/models.go +++ /dev/null @@ -1,34 +0,0 @@ -package safeline - -type BaseResponse interface { - GetErrCode() *string - GetErrMsg() *string -} - -type baseResponse struct { - ErrCode *string `json:"err,omitempty"` - ErrMsg *string `json:"msg,omitempty"` -} - -func (r *baseResponse) GetErrCode() *string { - return r.ErrCode -} - -func (r *baseResponse) GetErrMsg() *string { - return r.ErrMsg -} - -type UpdateCertificateRequest struct { - Id int32 `json:"id"` - Type int32 `json:"type"` - Manual *UpdateCertificateRequestBodyManul `json:"manual"` -} - -type UpdateCertificateRequestBodyManul struct { - Crt string `json:"crt"` - Key string `json:"key"` -} - -type UpdateCertificateResponse struct { - baseResponse -} diff --git a/internal/pkg/sdk3rd/safeline/types.go b/internal/pkg/sdk3rd/safeline/types.go new file mode 100644 index 00000000..16d44397 --- /dev/null +++ b/internal/pkg/sdk3rd/safeline/types.go @@ -0,0 +1,34 @@ +package safeline + +type apiResponse interface { + GetErrCode() string + GetErrMsg() string +} + +type apiResponseBase struct { + ErrCode *string `json:"err,omitempty"` + ErrMsg *string `json:"msg,omitempty"` +} + +func (r *apiResponseBase) GetErrCode() string { + if r.ErrCode == nil { + return "" + } + + return *r.ErrCode +} + +func (r *apiResponseBase) GetErrMsg() string { + if r.ErrMsg == nil { + return "" + } + + return *r.ErrMsg +} + +var _ apiResponse = (*apiResponseBase)(nil) + +type CertificateManul struct { + Crt string `json:"crt"` + Key string `json:"key"` +} diff --git a/internal/pkg/sdk3rd/ucloud/udnr/api_add_domain_dns.go b/internal/pkg/sdk3rd/ucloud/udnr/api_add_domain_dns.go new file mode 100644 index 00000000..d0cfe4c5 --- /dev/null +++ b/internal/pkg/sdk3rd/ucloud/udnr/api_add_domain_dns.go @@ -0,0 +1,44 @@ +package udnr + +import ( + "github.com/ucloud/ucloud-sdk-go/ucloud/request" + "github.com/ucloud/ucloud-sdk-go/ucloud/response" +) + +type AddDomainDNSRequest struct { + request.CommonBase + + Dn *string `required:"true"` + DnsType *string `required:"true"` + RecordName *string `required:"true"` + Content *string `required:"true"` + TTL *int `required:"true"` + Prio *int `required:"false"` +} + +type AddDomainDNSResponse struct { + response.CommonBase +} + +func (c *UDNRClient) NewAddDomainDNSRequest() *AddDomainDNSRequest { + req := &AddDomainDNSRequest{} + + c.Client.SetupRequest(req) + + req.SetRetryable(false) + return req +} + +func (c *UDNRClient) AddDomainDNS(req *AddDomainDNSRequest) (*AddDomainDNSResponse, error) { + var err error + var res AddDomainDNSResponse + + reqCopier := *req + + err = c.Client.InvokeAction("UdnrDomainDNSAdd", &reqCopier, &res) + if err != nil { + return &res, err + } + + return &res, nil +} diff --git a/internal/pkg/sdk3rd/ucloud/udnr/api_delete_domain_dns.go b/internal/pkg/sdk3rd/ucloud/udnr/api_delete_domain_dns.go new file mode 100644 index 00000000..11ddce01 --- /dev/null +++ b/internal/pkg/sdk3rd/ucloud/udnr/api_delete_domain_dns.go @@ -0,0 +1,42 @@ +package udnr + +import ( + "github.com/ucloud/ucloud-sdk-go/ucloud/request" + "github.com/ucloud/ucloud-sdk-go/ucloud/response" +) + +type DeleteDomainDNSRequest struct { + request.CommonBase + + Dn *string `required:"true"` + DnsType *string `required:"true"` + RecordName *string `required:"true"` + Content *string `required:"true"` +} + +type DeleteDomainDNSResponse struct { + response.CommonBase +} + +func (c *UDNRClient) NewDeleteDomainDNSRequest() *DeleteDomainDNSRequest { + req := &DeleteDomainDNSRequest{} + + c.Client.SetupRequest(req) + + req.SetRetryable(false) + return req +} + +func (c *UDNRClient) DeleteDomainDNS(req *DeleteDomainDNSRequest) (*DeleteDomainDNSResponse, error) { + var err error + var res DeleteDomainDNSResponse + + reqCopier := *req + + err = c.Client.InvokeAction("UdnrDeleteDnsRecord", &reqCopier, &res) + if err != nil { + return &res, err + } + + return &res, nil +} diff --git a/internal/pkg/sdk3rd/ucloud/udnr/api_query_domain_dns.go b/internal/pkg/sdk3rd/ucloud/udnr/api_query_domain_dns.go new file mode 100644 index 00000000..cabfd155 --- /dev/null +++ b/internal/pkg/sdk3rd/ucloud/udnr/api_query_domain_dns.go @@ -0,0 +1,41 @@ +package udnr + +import ( + "github.com/ucloud/ucloud-sdk-go/ucloud/request" + "github.com/ucloud/ucloud-sdk-go/ucloud/response" +) + +type QueryDomainDNSRequest struct { + request.CommonBase + + Dn *string `required:"true"` +} + +type QueryDomainDNSResponse struct { + response.CommonBase + + Data []DomainDNSRecord +} + +func (c *UDNRClient) NewQueryDomainDNSRequest() *QueryDomainDNSRequest { + req := &QueryDomainDNSRequest{} + + c.Client.SetupRequest(req) + + req.SetRetryable(false) + return req +} + +func (c *UDNRClient) QueryDomainDNS(req *QueryDomainDNSRequest) (*QueryDomainDNSResponse, error) { + var err error + var res QueryDomainDNSResponse + + reqCopier := *req + + err = c.Client.InvokeAction("UdnrDomainDNSQuery", &reqCopier, &res) + if err != nil { + return &res, err + } + + return &res, nil +} diff --git a/internal/pkg/sdk3rd/ucloud/udnr/apis.go b/internal/pkg/sdk3rd/ucloud/udnr/apis.go deleted file mode 100644 index af878e5b..00000000 --- a/internal/pkg/sdk3rd/ucloud/udnr/apis.go +++ /dev/null @@ -1,115 +0,0 @@ -package udnr - -import ( - "github.com/ucloud/ucloud-sdk-go/ucloud/request" - "github.com/ucloud/ucloud-sdk-go/ucloud/response" -) - -type QueryDomainDNSRequest struct { - request.CommonBase - - Dn *string `required:"true"` -} - -type QueryDomainDNSResponse struct { - response.CommonBase - - Data []DomainDNSRecord -} - -func (c *UDNRClient) NewQueryDomainDNSRequest() *QueryDomainDNSRequest { - req := &QueryDomainDNSRequest{} - - c.Client.SetupRequest(req) - - req.SetRetryable(false) - return req -} - -func (c *UDNRClient) QueryDomainDNS(req *QueryDomainDNSRequest) (*QueryDomainDNSResponse, error) { - var err error - var res QueryDomainDNSResponse - - reqCopier := *req - - err = c.Client.InvokeAction("UdnrDomainDNSQuery", &reqCopier, &res) - if err != nil { - return &res, err - } - - return &res, nil -} - -type AddDomainDNSRequest struct { - request.CommonBase - - Dn *string `required:"true"` - DnsType *string `required:"true"` - RecordName *string `required:"true"` - Content *string `required:"true"` - TTL *int `required:"true"` - Prio *int `required:"false"` -} - -type AddDomainDNSResponse struct { - response.CommonBase -} - -func (c *UDNRClient) NewAddDomainDNSRequest() *AddDomainDNSRequest { - req := &AddDomainDNSRequest{} - - c.Client.SetupRequest(req) - - req.SetRetryable(false) - return req -} - -func (c *UDNRClient) AddDomainDNS(req *AddDomainDNSRequest) (*AddDomainDNSResponse, error) { - var err error - var res AddDomainDNSResponse - - reqCopier := *req - - err = c.Client.InvokeAction("UdnrDomainDNSAdd", &reqCopier, &res) - if err != nil { - return &res, err - } - - return &res, nil -} - -type DeleteDomainDNSRequest struct { - request.CommonBase - - Dn *string `required:"true"` - DnsType *string `required:"true"` - RecordName *string `required:"true"` - Content *string `required:"true"` -} - -type DeleteDomainDNSResponse struct { - response.CommonBase -} - -func (c *UDNRClient) NewDeleteDomainDNSRequest() *DeleteDomainDNSRequest { - req := &DeleteDomainDNSRequest{} - - c.Client.SetupRequest(req) - - req.SetRetryable(false) - return req -} - -func (c *UDNRClient) DeleteDomainDNS(req *DeleteDomainDNSRequest) (*DeleteDomainDNSResponse, error) { - var err error - var res DeleteDomainDNSResponse - - reqCopier := *req - - err = c.Client.InvokeAction("UdnrDeleteDnsRecord", &reqCopier, &res) - if err != nil { - return &res, err - } - - return &res, nil -} diff --git a/internal/pkg/sdk3rd/ucloud/udnr/models.go b/internal/pkg/sdk3rd/ucloud/udnr/types.go similarity index 100% rename from internal/pkg/sdk3rd/ucloud/udnr/models.go rename to internal/pkg/sdk3rd/ucloud/udnr/types.go diff --git a/internal/pkg/sdk3rd/ucloud/ufile/apis.go b/internal/pkg/sdk3rd/ucloud/ufile/api_add_ufile_ssl_cert.go similarity index 100% rename from internal/pkg/sdk3rd/ucloud/ufile/apis.go rename to internal/pkg/sdk3rd/ucloud/ufile/api_add_ufile_ssl_cert.go diff --git a/internal/pkg/sdk3rd/ucloud/ussl/api_download_certificate.go b/internal/pkg/sdk3rd/ucloud/ussl/api_download_certificate.go new file mode 100644 index 00000000..3d262e9e --- /dev/null +++ b/internal/pkg/sdk3rd/ucloud/ussl/api_download_certificate.go @@ -0,0 +1,43 @@ +package ussl + +import ( + "github.com/ucloud/ucloud-sdk-go/ucloud/request" + "github.com/ucloud/ucloud-sdk-go/ucloud/response" +) + +type DownloadCertificateRequest struct { + request.CommonBase + + CertificateID *int `required:"true"` +} + +type DownloadCertificateResponse struct { + response.CommonBase + + CertificateUrl string + CertCA *CertificateDownloadInfo + Certificate *CertificateDownloadInfo +} + +func (c *USSLClient) NewDownloadCertificateRequest() *DownloadCertificateRequest { + req := &DownloadCertificateRequest{} + + c.Client.SetupRequest(req) + + req.SetRetryable(false) + return req +} + +func (c *USSLClient) DownloadCertificate(req *DownloadCertificateRequest) (*DownloadCertificateResponse, error) { + var err error + var res DownloadCertificateResponse + + reqCopier := *req + + err = c.Client.InvokeAction("DownloadCertificate", &reqCopier, &res) + if err != nil { + return &res, err + } + + return &res, nil +} diff --git a/internal/pkg/sdk3rd/ucloud/ussl/api_get_certificate_detail_info.go b/internal/pkg/sdk3rd/ucloud/ussl/api_get_certificate_detail_info.go new file mode 100644 index 00000000..2ab11aa7 --- /dev/null +++ b/internal/pkg/sdk3rd/ucloud/ussl/api_get_certificate_detail_info.go @@ -0,0 +1,41 @@ +package ussl + +import ( + "github.com/ucloud/ucloud-sdk-go/ucloud/request" + "github.com/ucloud/ucloud-sdk-go/ucloud/response" +) + +type GetCertificateDetailInfoRequest struct { + request.CommonBase + + CertificateID *int `required:"true"` +} + +type GetCertificateDetailInfoResponse struct { + response.CommonBase + + CertificateInfo *CertificateInfo +} + +func (c *USSLClient) NewGetCertificateDetailInfoRequest() *GetCertificateDetailInfoRequest { + req := &GetCertificateDetailInfoRequest{} + + c.Client.SetupRequest(req) + + req.SetRetryable(false) + return req +} + +func (c *USSLClient) GetCertificateDetailInfo(req *GetCertificateDetailInfoRequest) (*GetCertificateDetailInfoResponse, error) { + var err error + var res GetCertificateDetailInfoResponse + + reqCopier := *req + + err = c.Client.InvokeAction("GetCertificateDetailInfo", &reqCopier, &res) + if err != nil { + return &res, err + } + + return &res, nil +} diff --git a/internal/pkg/sdk3rd/ucloud/ussl/api_get_certificate_list.go b/internal/pkg/sdk3rd/ucloud/ussl/api_get_certificate_list.go new file mode 100644 index 00000000..e746335d --- /dev/null +++ b/internal/pkg/sdk3rd/ucloud/ussl/api_get_certificate_list.go @@ -0,0 +1,49 @@ +package ussl + +import ( + "github.com/ucloud/ucloud-sdk-go/ucloud/request" + "github.com/ucloud/ucloud-sdk-go/ucloud/response" +) + +type GetCertificateListRequest struct { + request.CommonBase + + Mode *string `required:"true"` + StateCode *string `required:"false"` + Brand *string `required:"false"` + CaOrganization *string `required:"false"` + Domain *string `required:"false"` + Sort *string `required:"false"` + Page *int `required:"false"` + PageSize *int `required:"false"` +} + +type GetCertificateListResponse struct { + response.CommonBase + + CertificateList []*CertificateListItem + TotalCount int +} + +func (c *USSLClient) NewGetCertificateListRequest() *GetCertificateListRequest { + req := &GetCertificateListRequest{} + + c.Client.SetupRequest(req) + + req.SetRetryable(false) + return req +} + +func (c *USSLClient) GetCertificateList(req *GetCertificateListRequest) (*GetCertificateListResponse, error) { + var err error + var res GetCertificateListResponse + + reqCopier := *req + + err = c.Client.InvokeAction("GetCertificateList", &reqCopier, &res) + if err != nil { + return &res, err + } + + return &res, nil +} diff --git a/internal/pkg/sdk3rd/ucloud/ussl/api_upload_normal_certificate.go b/internal/pkg/sdk3rd/ucloud/ussl/api_upload_normal_certificate.go new file mode 100644 index 00000000..1a99e839 --- /dev/null +++ b/internal/pkg/sdk3rd/ucloud/ussl/api_upload_normal_certificate.go @@ -0,0 +1,46 @@ +package ussl + +import ( + "github.com/ucloud/ucloud-sdk-go/ucloud/request" + "github.com/ucloud/ucloud-sdk-go/ucloud/response" +) + +type UploadNormalCertificateRequest struct { + request.CommonBase + + CertificateName *string `required:"true"` + SslPublicKey *string `required:"true"` + SslPrivateKey *string `required:"true"` + SslMD5 *string `required:"true"` + SslCaKey *string `required:"false"` +} + +type UploadNormalCertificateResponse struct { + response.CommonBase + + CertificateID int + LongResourceID string +} + +func (c *USSLClient) NewUploadNormalCertificateRequest() *UploadNormalCertificateRequest { + req := &UploadNormalCertificateRequest{} + + c.Client.SetupRequest(req) + + req.SetRetryable(false) + return req +} + +func (c *USSLClient) UploadNormalCertificate(req *UploadNormalCertificateRequest) (*UploadNormalCertificateResponse, error) { + var err error + var res UploadNormalCertificateResponse + + reqCopier := *req + + err = c.Client.InvokeAction("UploadNormalCertificate", &reqCopier, &res) + if err != nil { + return &res, err + } + + return &res, nil +} diff --git a/internal/pkg/sdk3rd/ucloud/ussl/apis.go b/internal/pkg/sdk3rd/ucloud/ussl/apis.go deleted file mode 100644 index d9ec7674..00000000 --- a/internal/pkg/sdk3rd/ucloud/ussl/apis.go +++ /dev/null @@ -1,161 +0,0 @@ -package ussl - -import ( - "github.com/ucloud/ucloud-sdk-go/ucloud/request" - "github.com/ucloud/ucloud-sdk-go/ucloud/response" -) - -type UploadNormalCertificateRequest struct { - request.CommonBase - - CertificateName *string `required:"true"` - SslPublicKey *string `required:"true"` - SslPrivateKey *string `required:"true"` - SslMD5 *string `required:"true"` - SslCaKey *string `required:"false"` -} - -type UploadNormalCertificateResponse struct { - response.CommonBase - - CertificateID int - LongResourceID string -} - -func (c *USSLClient) NewUploadNormalCertificateRequest() *UploadNormalCertificateRequest { - req := &UploadNormalCertificateRequest{} - - c.Client.SetupRequest(req) - - req.SetRetryable(false) - return req -} - -func (c *USSLClient) UploadNormalCertificate(req *UploadNormalCertificateRequest) (*UploadNormalCertificateResponse, error) { - var err error - var res UploadNormalCertificateResponse - - reqCopier := *req - - err = c.Client.InvokeAction("UploadNormalCertificate", &reqCopier, &res) - if err != nil { - return &res, err - } - - return &res, nil -} - -type GetCertificateListRequest struct { - request.CommonBase - - Mode *string `required:"true"` - StateCode *string `required:"false"` - Brand *string `required:"false"` - CaOrganization *string `required:"false"` - Domain *string `required:"false"` - Sort *string `required:"false"` - Page *int `required:"false"` - PageSize *int `required:"false"` -} - -type GetCertificateListResponse struct { - response.CommonBase - - CertificateList []*CertificateListItem - TotalCount int -} - -func (c *USSLClient) NewGetCertificateListRequest() *GetCertificateListRequest { - req := &GetCertificateListRequest{} - - c.Client.SetupRequest(req) - - req.SetRetryable(false) - return req -} - -func (c *USSLClient) GetCertificateList(req *GetCertificateListRequest) (*GetCertificateListResponse, error) { - var err error - var res GetCertificateListResponse - - reqCopier := *req - - err = c.Client.InvokeAction("GetCertificateList", &reqCopier, &res) - if err != nil { - return &res, err - } - - return &res, nil -} - -type GetCertificateDetailInfoRequest struct { - request.CommonBase - - CertificateID *int `required:"true"` -} - -type GetCertificateDetailInfoResponse struct { - response.CommonBase - - CertificateInfo *CertificateInfo -} - -func (c *USSLClient) NewGetCertificateDetailInfoRequest() *GetCertificateDetailInfoRequest { - req := &GetCertificateDetailInfoRequest{} - - c.Client.SetupRequest(req) - - req.SetRetryable(false) - return req -} - -func (c *USSLClient) GetCertificateDetailInfo(req *GetCertificateDetailInfoRequest) (*GetCertificateDetailInfoResponse, error) { - var err error - var res GetCertificateDetailInfoResponse - - reqCopier := *req - - err = c.Client.InvokeAction("GetCertificateDetailInfo", &reqCopier, &res) - if err != nil { - return &res, err - } - - return &res, nil -} - -type DownloadCertificateRequest struct { - request.CommonBase - - CertificateID *int `required:"true"` -} - -type DownloadCertificateResponse struct { - response.CommonBase - - CertificateUrl string - CertCA *CertificateDownloadInfo - Certificate *CertificateDownloadInfo -} - -func (c *USSLClient) NewDownloadCertificateRequest() *DownloadCertificateRequest { - req := &DownloadCertificateRequest{} - - c.Client.SetupRequest(req) - - req.SetRetryable(false) - return req -} - -func (c *USSLClient) DownloadCertificate(req *DownloadCertificateRequest) (*DownloadCertificateResponse, error) { - var err error - var res DownloadCertificateResponse - - reqCopier := *req - - err = c.Client.InvokeAction("DownloadCertificate", &reqCopier, &res) - if err != nil { - return &res, err - } - - return &res, nil -} diff --git a/internal/pkg/sdk3rd/ucloud/ussl/models.go b/internal/pkg/sdk3rd/ucloud/ussl/types.go similarity index 100% rename from internal/pkg/sdk3rd/ucloud/ussl/models.go rename to internal/pkg/sdk3rd/ucloud/ussl/types.go diff --git a/internal/pkg/sdk3rd/upyun/console/api.go b/internal/pkg/sdk3rd/upyun/console/api.go deleted file mode 100644 index ce62d3a6..00000000 --- a/internal/pkg/sdk3rd/upyun/console/api.go +++ /dev/null @@ -1,83 +0,0 @@ -package console - -import ( - "encoding/json" - "errors" - "fmt" - "net/http" -) - -func (c *Client) ensureCookieExists() error { - if c.loginCookie != "" { - return nil - } - - req := &signinRequest{Username: c.username, Password: c.password} - res, err := c.sendRequest(http.MethodPost, "/accounts/signin/", req) - if err != nil { - return err - } - - resp := &signinResponse{} - if err := json.Unmarshal(res.Body(), &resp); err != nil { - return fmt.Errorf("upyun api error: failed to unmarshal response: %w", err) - } else if !resp.Data.Result { - return errors.New("upyun console signin failed") - } - - c.loginCookie = res.Header().Get("Set-Cookie") - - return nil -} - -func (c *Client) UploadHttpsCertificate(req *UploadHttpsCertificateRequest) (*UploadHttpsCertificateResponse, error) { - if err := c.ensureCookieExists(); err != nil { - return nil, err - } - - resp := &UploadHttpsCertificateResponse{} - err := c.sendRequestWithResult(http.MethodPost, "/api/https/certificate/", req, resp) - return resp, err -} - -func (c *Client) GetHttpsCertificateManager(certificateId string) (*GetHttpsCertificateManagerResponse, error) { - if err := c.ensureCookieExists(); err != nil { - return nil, err - } - - req := &GetHttpsCertificateManagerRequest{CertificateId: certificateId} - resp := &GetHttpsCertificateManagerResponse{} - err := c.sendRequestWithResult(http.MethodGet, "/api/https/certificate/manager/", req, resp) - return resp, err -} - -func (c *Client) UpdateHttpsCertificateManager(req *UpdateHttpsCertificateManagerRequest) (*UpdateHttpsCertificateManagerResponse, error) { - if err := c.ensureCookieExists(); err != nil { - return nil, err - } - - resp := &UpdateHttpsCertificateManagerResponse{} - err := c.sendRequestWithResult(http.MethodPost, "/api/https/certificate/manager", req, resp) - return resp, err -} - -func (c *Client) GetHttpsServiceManager(domain string) (*GetHttpsServiceManagerResponse, error) { - if err := c.ensureCookieExists(); err != nil { - return nil, err - } - - req := &GetHttpsServiceManagerRequest{Domain: domain} - resp := &GetHttpsServiceManagerResponse{} - err := c.sendRequestWithResult(http.MethodGet, "/api/https/services/manager", req, resp) - return resp, err -} - -func (c *Client) MigrateHttpsDomain(req *MigrateHttpsDomainRequest) (*MigrateHttpsDomainResponse, error) { - if err := c.ensureCookieExists(); err != nil { - return nil, err - } - - resp := &MigrateHttpsDomainResponse{} - err := c.sendRequestWithResult(http.MethodPost, "/api/https/migrate/domain", req, resp) - return resp, err -} diff --git a/internal/pkg/sdk3rd/upyun/console/api_get_https_certificate_manager.go b/internal/pkg/sdk3rd/upyun/console/api_get_https_certificate_manager.go new file mode 100644 index 00000000..c2268117 --- /dev/null +++ b/internal/pkg/sdk3rd/upyun/console/api_get_https_certificate_manager.go @@ -0,0 +1,55 @@ +package console + +import ( + "context" + "fmt" + "net/http" +) + +type HttpsCertificateManagerDomain struct { + Name string `json:"name"` + Type string `json:"type"` + BucketId int64 `json:"bucket_id"` + BucketName string `json:"bucket_name"` +} + +type GetHttpsCertificateManagerResponse struct { + apiResponseBase + + Data *struct { + apiResponseBaseData + + AuthenticateNum int32 `json:"authenticate_num"` + AuthenticateDomains []string `json:"authenticate_domain"` + Domains []HttpsCertificateManagerDomain `json:"domains"` + } `json:"data,omitempty"` +} + +func (c *Client) GetHttpsCertificateManager(certificateId string) (*GetHttpsCertificateManagerResponse, error) { + return c.GetHttpsCertificateManagerWithContext(context.Background(), certificateId) +} + +func (c *Client) GetHttpsCertificateManagerWithContext(ctx context.Context, certificateId string) (*GetHttpsCertificateManagerResponse, error) { + if certificateId == "" { + return nil, fmt.Errorf("sdkerr: unset certificateId") + } + + if err := c.ensureCookieExists(); err != nil { + return nil, err + } + + httpreq, err := c.newRequest(http.MethodGet, "/api/https/certificate/manager/") + if err != nil { + return nil, err + } else { + httpreq.SetQueryParam("certificate_id", certificateId) + httpreq.SetContext(ctx) + } + + result := &GetHttpsCertificateManagerResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/upyun/console/api_get_https_service_manager.go b/internal/pkg/sdk3rd/upyun/console/api_get_https_service_manager.go new file mode 100644 index 00000000..debc4fe9 --- /dev/null +++ b/internal/pkg/sdk3rd/upyun/console/api_get_https_service_manager.go @@ -0,0 +1,60 @@ +package console + +import ( + "context" + "fmt" + "net/http" +) + +type GetHttpsServiceManagerResponse struct { + apiResponseBase + Data *struct { + apiResponseBaseData + Status int32 `json:"status"` + Domains []HttpsServiceManagerDomain `json:"result"` + } `json:"data,omitempty"` +} + +type HttpsServiceManagerDomain struct { + CertificateId string `json:"certificate_id"` + CommonName string `json:"commonName"` + Https bool `json:"https"` + ForceHttps bool `json:"force_https"` + PaymentType string `json:"payment_type"` + DomainType string `json:"domain_type"` + Validity HttpsServiceManagerDomainValidity `json:"validity"` +} + +type HttpsServiceManagerDomainValidity struct { + Start int64 `json:"start"` + End int64 `json:"end"` +} + +func (c *Client) GetHttpsServiceManager(domain string) (*GetHttpsServiceManagerResponse, error) { + return c.GetHttpsServiceManagerWithContext(context.Background(), domain) +} + +func (c *Client) GetHttpsServiceManagerWithContext(ctx context.Context, domain string) (*GetHttpsServiceManagerResponse, error) { + if domain == "" { + return nil, fmt.Errorf("sdkerr: unset domain") + } + + if err := c.ensureCookieExists(); err != nil { + return nil, err + } + + httpreq, err := c.newRequest(http.MethodGet, "/api/https/services/manager") + if err != nil { + return nil, err + } else { + httpreq.SetQueryParam("domain", domain) + httpreq.SetContext(ctx) + } + + result := &GetHttpsServiceManagerResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/upyun/console/api_migrate_https_domain.go b/internal/pkg/sdk3rd/upyun/console/api_migrate_https_domain.go new file mode 100644 index 00000000..3d1f8985 --- /dev/null +++ b/internal/pkg/sdk3rd/upyun/console/api_migrate_https_domain.go @@ -0,0 +1,46 @@ +package console + +import ( + "context" + "net/http" +) + +type MigrateHttpsDomainRequest struct { + CertificateId string `json:"crt_id"` + Domain string `json:"domain_name"` +} + +type MigrateHttpsDomainResponse struct { + apiResponseBase + + Data *struct { + apiResponseBaseData + + Status bool `json:"status"` + } `json:"data,omitempty"` +} + +func (c *Client) MigrateHttpsDomain(req *MigrateHttpsDomainRequest) (*MigrateHttpsDomainResponse, error) { + return c.MigrateHttpsDomainWithContext(context.Background(), req) +} + +func (c *Client) MigrateHttpsDomainWithContext(ctx context.Context, req *MigrateHttpsDomainRequest) (*MigrateHttpsDomainResponse, error) { + if err := c.ensureCookieExists(); err != nil { + return nil, err + } + + httpreq, err := c.newRequest(http.MethodPost, "/api/https/migrate/domain") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &MigrateHttpsDomainResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/upyun/console/api_update_https_certificate_manager.go b/internal/pkg/sdk3rd/upyun/console/api_update_https_certificate_manager.go new file mode 100644 index 00000000..f8c4a9ea --- /dev/null +++ b/internal/pkg/sdk3rd/upyun/console/api_update_https_certificate_manager.go @@ -0,0 +1,48 @@ +package console + +import ( + "context" + "net/http" +) + +type UpdateHttpsCertificateManagerRequest struct { + CertificateId string `json:"certificate_id"` + Domain string `json:"domain"` + Https bool `json:"https"` + ForceHttps bool `json:"force_https"` +} + +type UpdateHttpsCertificateManagerResponse struct { + apiResponseBase + + Data *struct { + apiResponseBaseData + + Status bool `json:"status"` + } `json:"data,omitempty"` +} + +func (c *Client) UpdateHttpsCertificateManager(req *UpdateHttpsCertificateManagerRequest) (*UpdateHttpsCertificateManagerResponse, error) { + return c.UpdateHttpsCertificateManagerWithContext(context.Background(), req) +} + +func (c *Client) UpdateHttpsCertificateManagerWithContext(ctx context.Context, req *UpdateHttpsCertificateManagerRequest) (*UpdateHttpsCertificateManagerResponse, error) { + if err := c.ensureCookieExists(); err != nil { + return nil, err + } + + httpreq, err := c.newRequest(http.MethodPost, "/api/https/certificate/manager") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &UpdateHttpsCertificateManagerResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/upyun/console/api_upload_https_certificate.go b/internal/pkg/sdk3rd/upyun/console/api_upload_https_certificate.go new file mode 100644 index 00000000..eaf99b51 --- /dev/null +++ b/internal/pkg/sdk3rd/upyun/console/api_upload_https_certificate.go @@ -0,0 +1,51 @@ +package console + +import ( + "context" + "net/http" +) + +type UploadHttpsCertificateRequest struct { + Certificate string `json:"certificate"` + PrivateKey string `json:"private_key"` +} + +type UploadHttpsCertificateResponse struct { + apiResponseBase + + Data *struct { + apiResponseBaseData + + Status int32 `json:"status"` + Result struct { + CertificateId string `json:"certificate_id"` + CommonName string `json:"commonName"` + Serial string `json:"serial"` + } `json:"result"` + } `json:"data,omitempty"` +} + +func (c *Client) UploadHttpsCertificate(req *UploadHttpsCertificateRequest) (*UploadHttpsCertificateResponse, error) { + return c.UploadHttpsCertificateWithContext(context.Background(), req) +} + +func (c *Client) UploadHttpsCertificateWithContext(ctx context.Context, req *UploadHttpsCertificateRequest) (*UploadHttpsCertificateResponse, error) { + if err := c.ensureCookieExists(); err != nil { + return nil, err + } + + httpreq, err := c.newRequest(http.MethodPost, "/api/https/certificate/") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &UploadHttpsCertificateResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/upyun/console/client.go b/internal/pkg/sdk3rd/upyun/console/client.go index e9202d91..7af3e7ae 100644 --- a/internal/pkg/sdk3rd/upyun/console/client.go +++ b/internal/pkg/sdk3rd/upyun/console/client.go @@ -2,9 +2,10 @@ package console import ( "encoding/json" + "errors" "fmt" "net/http" - "strings" + "sync" "time" "github.com/go-resty/resty/v2" @@ -14,18 +15,28 @@ type Client struct { username string password string - loginCookie string + loginCookie string + loginCookieMtx sync.Mutex client *resty.Client } -func NewClient(username, password string) *Client { +func NewClient(username, password string) (*Client, error) { + if username == "" { + return nil, fmt.Errorf("sdkerr: unset username") + } + if password == "" { + return nil, fmt.Errorf("sdkerr: unset password") + } + client := &Client{ username: username, password: password, } client.client = resty.New(). SetBaseURL("https://console.upyun.com"). + SetHeader("Accept", "application/json"). + SetHeader("Content-Type", "application/json"). SetHeader("User-Agent", "certimate"). SetPreRequestHook(func(c *resty.Client, req *http.Request) error { if client.loginCookie != "" { @@ -35,64 +46,107 @@ func NewClient(username, password string) *Client { return nil }) - return client + return client, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { +func (c *Client) SetTimeout(timeout time.Duration) *Client { c.client.SetTimeout(timeout) return c } -func (c *Client) sendRequest(method string, path string, params interface{}) (*resty.Response, error) { - req := c.client.R() - if strings.EqualFold(method, http.MethodGet) { - qs := make(map[string]string) - if params != nil { - temp := make(map[string]any) - jsonb, _ := json.Marshal(params) - json.Unmarshal(jsonb, &temp) - for k, v := range temp { - if v != nil { - qs[k] = fmt.Sprintf("%v", v) - } - } - } - - req = req.SetQueryParams(qs) - } else { - req = req.SetHeader("Content-Type", "application/json").SetBody(params) +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") } - resp, err := req.Execute(method, path) + req := c.client.R() + req.Method = method + req.URL = path + return req, nil +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + // WARN: + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. + + resp, err := req.Send() if err != nil { - return resp, fmt.Errorf("upyun api error: failed to send request: %w", err) + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) } else if resp.IsError() { - return resp, fmt.Errorf("upyun api error: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) } return resp, nil } -func (c *Client) sendRequestWithResult(method string, path string, params interface{}, result interface{}) error { - resp, err := c.sendRequest(method, path, params) +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + resp, err := c.doRequest(req) if err != nil { if resp != nil { - json.Unmarshal(resp.Body(), &result) + json.Unmarshal(resp.Body(), &res) } + return resp, err + } + + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) + } else { + if tdata := res.GetData(); tdata == nil { + return resp, fmt.Errorf("sdkerr: empty data") + } else if terrcode := tdata.GetErrorCode(); terrcode != 0 { + return resp, fmt.Errorf("sdkerr: code='%d', message='%s'", terrcode, tdata.GetMessage()) + } + } + } + + return resp, nil +} + +func (c *Client) ensureCookieExists() error { + c.loginCookieMtx.Lock() + defer c.loginCookieMtx.Unlock() + if c.loginCookie != "" { + return nil + } + + httpreq, err := c.newRequest(http.MethodPost, "/accounts/signin/") + if err != nil { return err + } else { + httpreq.SetBody(map[string]string{ + "username": c.username, + "password": c.password, + }) } - if err := json.Unmarshal(resp.Body(), &result); err != nil { - return fmt.Errorf("upyun api error: failed to unmarshal response: %w", err) + type signinResponse struct { + apiResponseBase + Data *struct { + apiResponseBaseData + Result bool `json:"result"` + } `json:"data,omitempty"` } - tresp := &baseResponse{} - if err := json.Unmarshal(resp.Body(), &tresp); err != nil { - return fmt.Errorf("upyun api error: failed to unmarshal response: %w", err) - } else if tdata := tresp.GetData(); tdata == nil { - return fmt.Errorf("upyun api error: empty data") - } else if errcode := tdata.GetErrorCode(); errcode > 0 { - return fmt.Errorf("upyun api error: code='%d', message='%s'", errcode, tdata.GetErrorMessage()) + result := &signinResponse{} + httpresp, err := c.doRequestWithResult(httpreq, result) + if err != nil { + return err + } else if !result.Data.Result { + return errors.New("sdkerr: failed to signin upyun console") + } else { + c.loginCookie = httpresp.Header().Get("Set-Cookie") } return nil diff --git a/internal/pkg/sdk3rd/upyun/console/models.go b/internal/pkg/sdk3rd/upyun/console/models.go deleted file mode 100644 index 12f2ab34..00000000 --- a/internal/pkg/sdk3rd/upyun/console/models.go +++ /dev/null @@ -1,141 +0,0 @@ -package console - -import ( - "encoding/json" -) - -type baseResponse struct { - Data *baseResponseData `json:"data,omitempty"` -} - -func (r *baseResponse) GetData() *baseResponseData { - return r.Data -} - -type baseResponseData struct { - ErrorCode json.Number `json:"error_code"` - ErrorMessage string `json:"message"` -} - -func (r *baseResponseData) GetErrorCode() int32 { - if r.ErrorCode.String() == "" { - return 0 - } - - errcode, err := r.ErrorCode.Int64() - if err != nil { - return -1 - } - - return int32(errcode) -} - -func (r *baseResponseData) GetErrorMessage() string { - return r.ErrorMessage -} - -type signinRequest struct { - Username string `json:"username"` - Password string `json:"password"` -} - -type signinResponse struct { - baseResponse - Data *struct { - baseResponseData - Result bool `json:"result"` - } `json:"data,omitempty"` -} - -type UploadHttpsCertificateRequest struct { - Certificate string `json:"certificate"` - PrivateKey string `json:"private_key"` -} - -type UploadHttpsCertificateResponse struct { - baseResponse - Data *struct { - baseResponseData - Status int32 `json:"status"` - Result struct { - CertificateId string `json:"certificate_id"` - CommonName string `json:"commonName"` - Serial string `json:"serial"` - } `json:"result"` - } `json:"data,omitempty"` -} - -type GetHttpsCertificateManagerRequest struct { - CertificateId string `json:"certificate_id"` -} - -type GetHttpsCertificateManagerResponse struct { - baseResponse - Data *struct { - baseResponseData - AuthenticateNum int32 `json:"authenticate_num"` - AuthenticateDomains []string `json:"authenticate_domain"` - Domains []HttpsCertificateManagerDomain `json:"domains"` - } `json:"data,omitempty"` -} - -type HttpsCertificateManagerDomain struct { - Name string `json:"name"` - Type string `json:"type"` - BucketId int64 `json:"bucket_id"` - BucketName string `json:"bucket_name"` -} - -type UpdateHttpsCertificateManagerRequest struct { - CertificateId string `json:"certificate_id"` - Domain string `json:"domain"` - Https bool `json:"https"` - ForceHttps bool `json:"force_https"` -} - -type UpdateHttpsCertificateManagerResponse struct { - baseResponse - Data *struct { - baseResponseData - Status bool `json:"status"` - } `json:"data,omitempty"` -} - -type GetHttpsServiceManagerRequest struct { - Domain string `json:"domain"` -} - -type GetHttpsServiceManagerResponse struct { - baseResponse - Data *struct { - baseResponseData - Status int32 `json:"status"` - Domains []HttpsServiceManagerDomain `json:"result"` - } `json:"data,omitempty"` -} - -type HttpsServiceManagerDomain struct { - CertificateId string `json:"certificate_id"` - CommonName string `json:"commonName"` - Https bool `json:"https"` - ForceHttps bool `json:"force_https"` - PaymentType string `json:"payment_type"` - DomainType string `json:"domain_type"` - Validity struct { - Start int64 `json:"start"` - End int64 `json:"end"` - } `json:"validity"` -} - -type MigrateHttpsDomainRequest struct { - CertificateId string `json:"crt_id"` - Domain string `json:"domain_name"` -} - -type MigrateHttpsDomainResponse struct { - baseResponse - Data *struct { - baseResponseData - Status bool `json:"status"` - } `json:"data,omitempty"` -} diff --git a/internal/pkg/sdk3rd/upyun/console/types.go b/internal/pkg/sdk3rd/upyun/console/types.go new file mode 100644 index 00000000..70d3c1c3 --- /dev/null +++ b/internal/pkg/sdk3rd/upyun/console/types.go @@ -0,0 +1,41 @@ +package console + +import ( + "encoding/json" +) + +type apiResponse interface { + GetData() *apiResponseBaseData +} + +type apiResponseBase struct { + Data *apiResponseBaseData `json:"data,omitempty"` +} + +func (r *apiResponseBase) GetData() *apiResponseBaseData { + return r.Data +} + +var _ apiResponse = (*apiResponseBase)(nil) + +type apiResponseBaseData struct { + ErrorCode json.Number `json:"error_code,omitempty"` + Message string `json:"message,omitempty"` +} + +func (r *apiResponseBaseData) GetErrorCode() int32 { + if r.ErrorCode.String() == "" { + return 0 + } + + errcode, err := r.ErrorCode.Int64() + if err != nil { + return -1 + } + + return int32(errcode) +} + +func (r *apiResponseBaseData) GetMessage() string { + return r.Message +} diff --git a/internal/pkg/sdk3rd/wangsu/cdn/api.go b/internal/pkg/sdk3rd/wangsu/cdn/api.go deleted file mode 100644 index 997c05bf..00000000 --- a/internal/pkg/sdk3rd/wangsu/cdn/api.go +++ /dev/null @@ -1,15 +0,0 @@ -package cdn - -import ( - "net/http" -) - -func (c *Client) BatchUpdateCertificateConfig(req *BatchUpdateCertificateConfigRequest) (*BatchUpdateCertificateConfigResponse, error) { - resp := &BatchUpdateCertificateConfigResponse{} - _, err := c.client.SendRequestWithResult(http.MethodPut, "/api/config/certificate/batch", req, resp) - if err != nil { - return resp, err - } - - return resp, err -} diff --git a/internal/pkg/sdk3rd/wangsu/cdn/api_batch_update_certificate_config.go b/internal/pkg/sdk3rd/wangsu/cdn/api_batch_update_certificate_config.go new file mode 100644 index 00000000..90598b0d --- /dev/null +++ b/internal/pkg/sdk3rd/wangsu/cdn/api_batch_update_certificate_config.go @@ -0,0 +1,36 @@ +package cdn + +import ( + "context" + "net/http" +) + +type BatchUpdateCertificateConfigRequest struct { + CertificateId int64 `json:"certificateId"` + DomainNames []string `json:"domainNames"` +} + +type BatchUpdateCertificateConfigResponse struct { + apiResponseBase +} + +func (c *Client) BatchUpdateCertificateConfig(req *BatchUpdateCertificateConfigRequest) (*BatchUpdateCertificateConfigResponse, error) { + return c.BatchUpdateCertificateConfigWithContext(context.Background(), req) +} + +func (c *Client) BatchUpdateCertificateConfigWithContext(ctx context.Context, req *BatchUpdateCertificateConfigRequest) (*BatchUpdateCertificateConfigResponse, error) { + httpreq, err := c.newRequest(http.MethodPut, "/api/config/certificate/batch") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &BatchUpdateCertificateConfigResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/wangsu/cdn/client.go b/internal/pkg/sdk3rd/wangsu/cdn/client.go index ac53e171..39d2f816 100644 --- a/internal/pkg/sdk3rd/wangsu/cdn/client.go +++ b/internal/pkg/sdk3rd/wangsu/cdn/client.go @@ -1,8 +1,11 @@ package cdn import ( + "fmt" "time" + "github.com/go-resty/resty/v2" + "github.com/usual2970/certimate/internal/pkg/sdk3rd/wangsu/openapi" ) @@ -10,11 +13,35 @@ type Client struct { client *openapi.Client } -func NewClient(accessKey, secretKey string) *Client { - return &Client{client: openapi.NewClient(accessKey, secretKey)} +func NewClient(accessKey, secretKey string) (*Client, error) { + client, err := openapi.NewClient(accessKey, secretKey) + if err != nil { + return nil, err + } + + return &Client{client: client}, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { - c.client.WithTimeout(timeout) +func (c *Client) SetTimeout(timeout time.Duration) *Client { + c.client.SetTimeout(timeout) return c } + +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + return c.client.NewRequest(method, path) +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + return c.client.DoRequest(req) +} + +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + resp, err := c.client.DoRequestWithResult(req, res) + if err == nil { + if tcode := res.GetCode(); tcode != "" && tcode != "0" { + return resp, fmt.Errorf("sdkerr: api error, code='%s', message='%s'", tcode, res.GetMessage()) + } + } + + return resp, err +} diff --git a/internal/pkg/sdk3rd/wangsu/cdn/models.go b/internal/pkg/sdk3rd/wangsu/cdn/models.go deleted file mode 100644 index 5bf934af..00000000 --- a/internal/pkg/sdk3rd/wangsu/cdn/models.go +++ /dev/null @@ -1,26 +0,0 @@ -package cdn - -import ( - "github.com/usual2970/certimate/internal/pkg/sdk3rd/wangsu/openapi" -) - -type baseResponse struct { - RequestId *string `json:"requestId,omitempty"` - Code *string `json:"code,omitempty"` - Message *string `json:"message,omitempty"` -} - -var _ openapi.Result = (*baseResponse)(nil) - -func (r *baseResponse) SetRequestId(requestId string) { - r.RequestId = &requestId -} - -type BatchUpdateCertificateConfigRequest struct { - CertificateId int64 `json:"certificateId" required:"true"` - DomainNames []string `json:"domainNames" required:"true"` -} - -type BatchUpdateCertificateConfigResponse struct { - baseResponse -} diff --git a/internal/pkg/sdk3rd/wangsu/cdn/types.go b/internal/pkg/sdk3rd/wangsu/cdn/types.go new file mode 100644 index 00000000..a436ba49 --- /dev/null +++ b/internal/pkg/sdk3rd/wangsu/cdn/types.go @@ -0,0 +1,29 @@ +package cdn + +type apiResponse interface { + GetCode() string + GetMessage() string +} + +type apiResponseBase struct { + Code *string `json:"code,omitempty"` + Message *string `json:"message,omitempty"` +} + +var _ apiResponse = (*apiResponseBase)(nil) + +func (r *apiResponseBase) GetCode() string { + if r.Code == nil { + return "" + } + + return *r.Code +} + +func (r *apiResponseBase) GetMessage() string { + if r.Message == nil { + return "" + } + + return *r.Message +} diff --git a/internal/pkg/sdk3rd/wangsu/cdnpro/api.go b/internal/pkg/sdk3rd/wangsu/cdnpro/api.go deleted file mode 100644 index c45e6921..00000000 --- a/internal/pkg/sdk3rd/wangsu/cdnpro/api.go +++ /dev/null @@ -1,70 +0,0 @@ -package cdnpro - -import ( - "fmt" - "net/http" - "net/url" - - "github.com/go-resty/resty/v2" -) - -func (c *Client) CreateCertificate(req *CreateCertificateRequest) (*CreateCertificateResponse, error) { - resp := &CreateCertificateResponse{} - rres, err := c.client.SendRequestWithResult(http.MethodPost, "/cdn/certificates", req, resp, func(r *resty.Request) { - r.SetHeader("X-CNC-Timestamp", fmt.Sprintf("%d", req.Timestamp)) - }) - if err != nil { - return resp, err - } - - resp.CertificateUrl = rres.Header().Get("Location") - return resp, err -} - -func (c *Client) UpdateCertificate(certificateId string, req *UpdateCertificateRequest) (*UpdateCertificateResponse, error) { - if certificateId == "" { - return nil, fmt.Errorf("wangsu api error: invalid parameter: certificateId") - } - - resp := &UpdateCertificateResponse{} - rres, err := c.client.SendRequestWithResult(http.MethodPatch, fmt.Sprintf("/cdn/certificates/%s", url.PathEscape(certificateId)), req, resp, func(r *resty.Request) { - r.SetHeader("X-CNC-Timestamp", fmt.Sprintf("%d", req.Timestamp)) - }) - if err != nil { - return resp, err - } - - resp.CertificateUrl = rres.Header().Get("Location") - return resp, err -} - -func (c *Client) GetHostnameDetail(hostname string) (*GetHostnameDetailResponse, error) { - if hostname == "" { - return nil, fmt.Errorf("wangsu api error: invalid parameter: hostname") - } - - resp := &GetHostnameDetailResponse{} - _, err := c.client.SendRequestWithResult(http.MethodGet, fmt.Sprintf("/cdn/hostnames/%s", url.PathEscape(hostname)), nil, resp) - return resp, err -} - -func (c *Client) CreateDeploymentTask(req *CreateDeploymentTaskRequest) (*CreateDeploymentTaskResponse, error) { - resp := &CreateDeploymentTaskResponse{} - rres, err := c.client.SendRequestWithResult(http.MethodPost, "/cdn/deploymentTasks", req, resp) - if err != nil { - return resp, err - } - - resp.DeploymentTaskUrl = rres.Header().Get("Location") - return resp, err -} - -func (c *Client) GetDeploymentTaskDetail(deploymentTaskId string) (*GetDeploymentTaskDetailResponse, error) { - if deploymentTaskId == "" { - return nil, fmt.Errorf("wangsu api error: invalid parameter: deploymentTaskId") - } - - resp := &GetDeploymentTaskDetailResponse{} - _, err := c.client.SendRequestWithResult(http.MethodGet, fmt.Sprintf("/cdn/deploymentTasks/%s", url.PathEscape(deploymentTaskId)), nil, resp) - return resp, err -} diff --git a/internal/pkg/sdk3rd/wangsu/cdnpro/api_create_certificate.go b/internal/pkg/sdk3rd/wangsu/cdnpro/api_create_certificate.go new file mode 100644 index 00000000..ef473dab --- /dev/null +++ b/internal/pkg/sdk3rd/wangsu/cdnpro/api_create_certificate.go @@ -0,0 +1,46 @@ +package cdnpro + +import ( + "context" + "fmt" + "net/http" +) + +type CreateCertificateRequest struct { + Timestamp int64 `json:"-"` + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + AutoRenew *string `json:"autoRenew,omitempty"` + ForceRenew *bool `json:"forceRenew,omitempty"` + NewVersion *CertificateVersionInfo `json:"newVersion,omitempty"` +} + +type CreateCertificateResponse struct { + apiResponseBase + + CertificateLocation string `json:"location,omitempty"` +} + +func (c *Client) CreateCertificate(req *CreateCertificateRequest) (*CreateCertificateResponse, error) { + return c.CreateCertificateWithContext(context.Background(), req) +} + +func (c *Client) CreateCertificateWithContext(ctx context.Context, req *CreateCertificateRequest) (*CreateCertificateResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/cdn/certificates") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetHeader("X-CNC-Timestamp", fmt.Sprintf("%d", req.Timestamp)) + httpreq.SetContext(ctx) + } + + result := &CreateCertificateResponse{} + if httpresp, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } else { + result.CertificateLocation = httpresp.Header().Get("Location") + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/wangsu/cdnpro/api_create_deployment_task.go b/internal/pkg/sdk3rd/wangsu/cdnpro/api_create_deployment_task.go new file mode 100644 index 00000000..0ba2fa68 --- /dev/null +++ b/internal/pkg/sdk3rd/wangsu/cdnpro/api_create_deployment_task.go @@ -0,0 +1,42 @@ +package cdnpro + +import ( + "context" + "net/http" +) + +type CreateDeploymentTaskRequest struct { + Name *string `json:"name,omitempty"` + Target *string `json:"target,omitempty"` + Actions *[]DeploymentTaskActionInfo `json:"actions,omitempty"` + Webhook *string `json:"webhook,omitempty"` +} + +type CreateDeploymentTaskResponse struct { + apiResponseBase + + DeploymentTaskLocation string `json:"location,omitempty"` +} + +func (c *Client) CreateDeploymentTask(req *CreateDeploymentTaskRequest) (*CreateDeploymentTaskResponse, error) { + return c.CreateDeploymentTaskWithContext(context.Background(), req) +} + +func (c *Client) CreateDeploymentTaskWithContext(ctx context.Context, req *CreateDeploymentTaskRequest) (*CreateDeploymentTaskResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/cdn/deploymentTasks") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &CreateDeploymentTaskResponse{} + if httpresp, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } else { + result.DeploymentTaskLocation = httpresp.Header().Get("Location") + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/wangsu/cdnpro/api_get_deployment_task_detail.go b/internal/pkg/sdk3rd/wangsu/cdnpro/api_get_deployment_task_detail.go new file mode 100644 index 00000000..9200fe97 --- /dev/null +++ b/internal/pkg/sdk3rd/wangsu/cdnpro/api_get_deployment_task_detail.go @@ -0,0 +1,45 @@ +package cdnpro + +import ( + "context" + "fmt" + "net/http" + "net/url" +) + +type GetDeploymentTaskDetailResponse struct { + apiResponseBase + + Name string `json:"name"` + Target string `json:"target"` + Actions []DeploymentTaskActionInfo `json:"actions"` + Status string `json:"status"` + StatusDetails string `json:"statusDetails"` + SubmissionTime string `json:"submissionTime"` + FinishTime string `json:"finishTime"` + ApiRequestId string `json:"apiRequestId"` +} + +func (c *Client) GetDeploymentTaskDetail(deploymentTaskId string) (*GetDeploymentTaskDetailResponse, error) { + return c.GetDeploymentTaskDetailWithContext(context.Background(), deploymentTaskId) +} + +func (c *Client) GetDeploymentTaskDetailWithContext(ctx context.Context, deploymentTaskId string) (*GetDeploymentTaskDetailResponse, error) { + if deploymentTaskId == "" { + return nil, fmt.Errorf("sdkerr: unset deploymentTaskId") + } + + httpreq, err := c.newRequest(http.MethodGet, fmt.Sprintf("/cdn/deploymentTasks/%s", url.PathEscape(deploymentTaskId))) + if err != nil { + return nil, err + } else { + httpreq.SetContext(ctx) + } + + result := &GetDeploymentTaskDetailResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/wangsu/cdnpro/api_get_hostname_detail.go b/internal/pkg/sdk3rd/wangsu/cdnpro/api_get_hostname_detail.go new file mode 100644 index 00000000..85796c8c --- /dev/null +++ b/internal/pkg/sdk3rd/wangsu/cdnpro/api_get_hostname_detail.go @@ -0,0 +1,40 @@ +package cdnpro + +import ( + "context" + "fmt" + "net/http" + "net/url" +) + +type GetHostnameDetailResponse struct { + apiResponseBase + + Hostname string `json:"hostname"` + PropertyInProduction *HostnamePropertyInfo `json:"propertyInProduction,omitempty"` + PropertyInStaging *HostnamePropertyInfo `json:"propertyInStaging,omitempty"` +} + +func (c *Client) GetHostnameDetail(hostname string) (*GetHostnameDetailResponse, error) { + return c.GetHostnameDetailWithContext(context.Background(), hostname) +} + +func (c *Client) GetHostnameDetailWithContext(ctx context.Context, hostname string) (*GetHostnameDetailResponse, error) { + if hostname == "" { + return nil, fmt.Errorf("sdkerr: unset hostname") + } + + httpreq, err := c.newRequest(http.MethodGet, fmt.Sprintf("/cdn/hostnames/%s", url.PathEscape(hostname))) + if err != nil { + return nil, err + } else { + httpreq.SetContext(ctx) + } + + result := &GetHostnameDetailResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/wangsu/cdnpro/api_update_certificate.go b/internal/pkg/sdk3rd/wangsu/cdnpro/api_update_certificate.go new file mode 100644 index 00000000..59859bbf --- /dev/null +++ b/internal/pkg/sdk3rd/wangsu/cdnpro/api_update_certificate.go @@ -0,0 +1,51 @@ +package cdnpro + +import ( + "context" + "fmt" + "net/http" + "net/url" +) + +type UpdateCertificateRequest struct { + Timestamp int64 `json:"-"` + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + AutoRenew *string `json:"autoRenew,omitempty"` + ForceRenew *bool `json:"forceRenew,omitempty"` + NewVersion *CertificateVersionInfo `json:"newVersion,omitempty"` +} + +type UpdateCertificateResponse struct { + apiResponseBase + + CertificateLocation string `json:"location,omitempty"` +} + +func (c *Client) UpdateCertificate(certificateId string, req *UpdateCertificateRequest) (*UpdateCertificateResponse, error) { + return c.UpdateCertificateWithContext(context.Background(), certificateId, req) +} + +func (c *Client) UpdateCertificateWithContext(ctx context.Context, certificateId string, req *UpdateCertificateRequest) (*UpdateCertificateResponse, error) { + if certificateId == "" { + return nil, fmt.Errorf("sdkerr: unset certificateId") + } + + httpreq, err := c.newRequest(http.MethodPatch, fmt.Sprintf("/cdn/certificates/%s", url.PathEscape(certificateId))) + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetHeader("X-CNC-Timestamp", fmt.Sprintf("%d", req.Timestamp)) + httpreq.SetContext(ctx) + } + + result := &UpdateCertificateResponse{} + if httpresp, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } else { + result.CertificateLocation = httpresp.Header().Get("Location") + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/wangsu/cdnpro/client.go b/internal/pkg/sdk3rd/wangsu/cdnpro/client.go index b5c0f530..2c3fa0cc 100644 --- a/internal/pkg/sdk3rd/wangsu/cdnpro/client.go +++ b/internal/pkg/sdk3rd/wangsu/cdnpro/client.go @@ -3,6 +3,8 @@ package cdnpro import ( "time" + "github.com/go-resty/resty/v2" + "github.com/usual2970/certimate/internal/pkg/sdk3rd/wangsu/openapi" ) @@ -10,11 +12,28 @@ type Client struct { client *openapi.Client } -func NewClient(accessKey, secretKey string) *Client { - return &Client{client: openapi.NewClient(accessKey, secretKey)} +func NewClient(accessKey, secretKey string) (*Client, error) { + client, err := openapi.NewClient(accessKey, secretKey) + if err != nil { + return nil, err + } + + return &Client{client: client}, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { - c.client.WithTimeout(timeout) +func (c *Client) SetTimeout(timeout time.Duration) *Client { + c.client.SetTimeout(timeout) return c } + +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + return c.client.NewRequest(method, path) +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + return c.client.DoRequest(req) +} + +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + return c.client.DoRequestWithResult(req, res) +} diff --git a/internal/pkg/sdk3rd/wangsu/cdnpro/models.go b/internal/pkg/sdk3rd/wangsu/cdnpro/models.go deleted file mode 100644 index 9cb1e648..00000000 --- a/internal/pkg/sdk3rd/wangsu/cdnpro/models.go +++ /dev/null @@ -1,108 +0,0 @@ -package cdnpro - -import ( - "github.com/usual2970/certimate/internal/pkg/sdk3rd/wangsu/openapi" -) - -type baseResponse struct { - RequestId *string `json:"requestId,omitempty"` - Code *string `json:"code,omitempty"` - Message *string `json:"message,omitempty"` -} - -var _ openapi.Result = (*baseResponse)(nil) - -func (r *baseResponse) SetRequestId(requestId string) { - r.RequestId = &requestId -} - -type CertificateVersion struct { - Comments *string `json:"comments,omitempty"` - PrivateKey *string `json:"privateKey,omitempty"` - Certificate *string `json:"certificate,omitempty"` - ChainCert *string `json:"chainCert,omitempty"` - IdentificationInfo *CertificateVersionIdentificationInfo `json:"identificationInfo,omitempty"` -} - -type CertificateVersionIdentificationInfo struct { - Country *string `json:"country,omitempty"` - State *string `json:"state,omitempty"` - City *string `json:"city,omitempty"` - Company *string `json:"company,omitempty"` - Department *string `json:"department,omitempty"` - CommonName *string `json:"commonName,omitempty" required:"true"` - Email *string `json:"email,omitempty"` - SubjectAlternativeNames *[]string `json:"subjectAlternativeNames,omitempty" required:"true"` -} - -type CreateCertificateRequest struct { - Timestamp int64 `json:"-"` - Name *string `json:"name,omitempty" required:"true"` - Description *string `json:"description,omitempty"` - AutoRenew *string `json:"autoRenew,omitempty"` - ForceRenew *bool `json:"forceRenew,omitempty"` - NewVersion *CertificateVersion `json:"newVersion,omitempty" required:"true"` -} - -type CreateCertificateResponse struct { - baseResponse - CertificateUrl string `json:"location,omitempty"` -} - -type UpdateCertificateRequest struct { - Timestamp int64 `json:"-"` - Name *string `json:"name,omitempty"` - Description *string `json:"description,omitempty"` - AutoRenew *string `json:"autoRenew,omitempty"` - ForceRenew *bool `json:"forceRenew,omitempty"` - NewVersion *CertificateVersion `json:"newVersion,omitempty" required:"true"` -} - -type UpdateCertificateResponse struct { - baseResponse - CertificateUrl string `json:"location,omitempty"` -} - -type HostnameProperty struct { - PropertyId string `json:"propertyId"` - Version int32 `json:"version"` - CertificateId *string `json:"certificateId,omitempty"` -} - -type GetHostnameDetailResponse struct { - baseResponse - Hostname string `json:"hostname"` - PropertyInProduction *HostnameProperty `json:"propertyInProduction,omitempty"` - PropertyInStaging *HostnameProperty `json:"propertyInStaging,omitempty"` -} - -type DeploymentTaskAction struct { - Action *string `json:"action,omitempty" required:"true"` - PropertyId *string `json:"propertyId,omitempty"` - CertificateId *string `json:"certificateId,omitempty"` - Version *int32 `json:"version,omitempty"` -} - -type CreateDeploymentTaskRequest struct { - Name *string `json:"name,omitempty"` - Target *string `json:"target,omitempty" required:"true"` - Actions *[]DeploymentTaskAction `json:"actions,omitempty" required:"true"` - Webhook *string `json:"webhook,omitempty"` -} - -type CreateDeploymentTaskResponse struct { - baseResponse - DeploymentTaskUrl string `json:"location,omitempty"` -} - -type GetDeploymentTaskDetailResponse struct { - baseResponse - Name string `json:"name"` - Target string `json:"target"` - Actions []DeploymentTaskAction `json:"actions"` - Status string `json:"status"` - StatusDetails string `json:"statusDetails"` - SubmissionTime string `json:"submissionTime"` - FinishTime string `json:"finishTime"` - ApiRequestId string `json:"apiRequestId"` -} diff --git a/internal/pkg/sdk3rd/wangsu/cdnpro/types.go b/internal/pkg/sdk3rd/wangsu/cdnpro/types.go new file mode 100644 index 00000000..d82d3b09 --- /dev/null +++ b/internal/pkg/sdk3rd/wangsu/cdnpro/types.go @@ -0,0 +1,61 @@ +package cdnpro + +type apiResponse interface { + GetCode() string + GetMessage() string +} + +type apiResponseBase struct { + Code *string `json:"code,omitempty"` + Message *string `json:"message,omitempty"` +} + +var _ apiResponse = (*apiResponseBase)(nil) + +func (r *apiResponseBase) GetCode() string { + if r.Code == nil { + return "" + } + + return *r.Code +} + +func (r *apiResponseBase) GetMessage() string { + if r.Message == nil { + return "" + } + + return *r.Message +} + +type CertificateVersionInfo struct { + Comments *string `json:"comments,omitempty"` + PrivateKey *string `json:"privateKey,omitempty"` + Certificate *string `json:"certificate,omitempty"` + ChainCert *string `json:"chainCert,omitempty"` + IdentificationInfo *CertificateVersionIdentificationInfo `json:"identificationInfo,omitempty"` +} + +type CertificateVersionIdentificationInfo struct { + Country *string `json:"country,omitempty"` + State *string `json:"state,omitempty"` + City *string `json:"city,omitempty"` + Company *string `json:"company,omitempty"` + Department *string `json:"department,omitempty"` + CommonName *string `json:"commonName,omitempty"` + Email *string `json:"email,omitempty"` + SubjectAlternativeNames *[]string `json:"subjectAlternativeNames,omitempty"` +} + +type HostnamePropertyInfo struct { + PropertyId string `json:"propertyId"` + Version int32 `json:"version"` + CertificateId *string `json:"certificateId,omitempty"` +} + +type DeploymentTaskActionInfo struct { + Action *string `json:"action,omitempty"` + PropertyId *string `json:"propertyId,omitempty"` + CertificateId *string `json:"certificateId,omitempty"` + Version *int32 `json:"version,omitempty"` +} diff --git a/internal/pkg/sdk3rd/wangsu/certificate/api.go b/internal/pkg/sdk3rd/wangsu/certificate/api.go deleted file mode 100644 index 22172d4e..00000000 --- a/internal/pkg/sdk3rd/wangsu/certificate/api.go +++ /dev/null @@ -1,42 +0,0 @@ -package certificate - -import ( - "fmt" - "net/http" - "net/url" -) - -func (c *Client) ListCertificates() (*ListCertificatesResponse, error) { - resp := &ListCertificatesResponse{} - _, err := c.client.SendRequestWithResult(http.MethodGet, "/api/ssl/certificate", nil, resp) - if err != nil { - return resp, err - } - - return resp, err -} - -func (c *Client) CreateCertificate(req *CreateCertificateRequest) (*CreateCertificateResponse, error) { - resp := &CreateCertificateResponse{} - rres, err := c.client.SendRequestWithResult(http.MethodPost, "/api/certificate", req, resp) - if err != nil { - return resp, err - } - - resp.CertificateUrl = rres.Header().Get("Location") - return resp, err -} - -func (c *Client) UpdateCertificate(certificateId string, req *UpdateCertificateRequest) (*UpdateCertificateResponse, error) { - if certificateId == "" { - return nil, fmt.Errorf("wangsu api error: invalid parameter: certificateId") - } - - resp := &UpdateCertificateResponse{} - _, err := c.client.SendRequestWithResult(http.MethodPut, fmt.Sprintf("/api/certificate/%s", url.PathEscape(certificateId)), req, resp) - if err != nil { - return resp, err - } - - return resp, err -} diff --git a/internal/pkg/sdk3rd/wangsu/certificate/api_create_certificate.go b/internal/pkg/sdk3rd/wangsu/certificate/api_create_certificate.go new file mode 100644 index 00000000..30ebb99d --- /dev/null +++ b/internal/pkg/sdk3rd/wangsu/certificate/api_create_certificate.go @@ -0,0 +1,42 @@ +package certificate + +import ( + "context" + "net/http" +) + +type CreateCertificateRequest struct { + Name *string `json:"name,omitempty"` + Certificate *string `json:"certificate,omitempty"` + PrivateKey *string `json:"privateKey,omitempty"` + Comment *string `json:"comment,omitempty" ` +} + +type CreateCertificateResponse struct { + apiResponseBase + + CertificateLocation string `json:"location,omitempty"` +} + +func (c *Client) CreateCertificate(req *CreateCertificateRequest) (*CreateCertificateResponse, error) { + return c.CreateCertificateWithContext(context.Background(), req) +} + +func (c *Client) CreateCertificateWithContext(ctx context.Context, req *CreateCertificateRequest) (*CreateCertificateResponse, error) { + httpreq, err := c.newRequest(http.MethodPost, "/api/certificate") + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &CreateCertificateResponse{} + if httpresp, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } else { + result.CertificateLocation = httpresp.Header().Get("Location") + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/wangsu/certificate/api_list_certificates.go b/internal/pkg/sdk3rd/wangsu/certificate/api_list_certificates.go new file mode 100644 index 00000000..e62c1276 --- /dev/null +++ b/internal/pkg/sdk3rd/wangsu/certificate/api_list_certificates.go @@ -0,0 +1,32 @@ +package certificate + +import ( + "context" + "net/http" +) + +type ListCertificatesResponse struct { + apiResponseBase + + Certificates []*CertificateRecord `json:"ssl-certificates,omitempty"` +} + +func (c *Client) ListCertificates() (*ListCertificatesResponse, error) { + return c.ListCertificatesWithContext(context.Background()) +} + +func (c *Client) ListCertificatesWithContext(ctx context.Context) (*ListCertificatesResponse, error) { + httpreq, err := c.newRequest(http.MethodGet, "/api/ssl/certificate") + if err != nil { + return nil, err + } else { + httpreq.SetContext(ctx) + } + + result := &ListCertificatesResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/wangsu/certificate/api_update_certificate.go b/internal/pkg/sdk3rd/wangsu/certificate/api_update_certificate.go new file mode 100644 index 00000000..2158b4f6 --- /dev/null +++ b/internal/pkg/sdk3rd/wangsu/certificate/api_update_certificate.go @@ -0,0 +1,44 @@ +package certificate + +import ( + "context" + "fmt" + "net/http" + "net/url" +) + +type UpdateCertificateRequest struct { + Name *string `json:"name,omitempty"` + Certificate *string `json:"certificate,omitempty"` + PrivateKey *string `json:"privateKey,omitempty"` + Comment *string `json:"comment,omitempty" ` +} + +type UpdateCertificateResponse struct { + apiResponseBase +} + +func (c *Client) UpdateCertificate(certificateId string, req *UpdateCertificateRequest) (*UpdateCertificateResponse, error) { + return c.UpdateCertificateWithContext(context.Background(), certificateId, req) +} + +func (c *Client) UpdateCertificateWithContext(ctx context.Context, certificateId string, req *UpdateCertificateRequest) (*UpdateCertificateResponse, error) { + if certificateId == "" { + return nil, fmt.Errorf("sdkerr: unset certificateId") + } + + httpreq, err := c.newRequest(http.MethodPut, fmt.Sprintf("/api/certificate/%s", url.PathEscape(certificateId))) + if err != nil { + return nil, err + } else { + httpreq.SetBody(req) + httpreq.SetContext(ctx) + } + + result := &UpdateCertificateResponse{} + if _, err := c.doRequestWithResult(httpreq, result); err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/pkg/sdk3rd/wangsu/certificate/client.go b/internal/pkg/sdk3rd/wangsu/certificate/client.go index 19f4cfaa..67b96aa5 100644 --- a/internal/pkg/sdk3rd/wangsu/certificate/client.go +++ b/internal/pkg/sdk3rd/wangsu/certificate/client.go @@ -3,6 +3,8 @@ package certificate import ( "time" + "github.com/go-resty/resty/v2" + "github.com/usual2970/certimate/internal/pkg/sdk3rd/wangsu/openapi" ) @@ -10,11 +12,28 @@ type Client struct { client *openapi.Client } -func NewClient(accessKey, secretKey string) *Client { - return &Client{client: openapi.NewClient(accessKey, secretKey)} +func NewClient(accessKey, secretKey string) (*Client, error) { + client, err := openapi.NewClient(accessKey, secretKey) + if err != nil { + return nil, err + } + + return &Client{client: client}, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { - c.client.WithTimeout(timeout) +func (c *Client) SetTimeout(timeout time.Duration) *Client { + c.client.SetTimeout(timeout) return c } + +func (c *Client) newRequest(method string, path string) (*resty.Request, error) { + return c.client.NewRequest(method, path) +} + +func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) { + return c.client.DoRequest(req) +} + +func (c *Client) doRequestWithResult(req *resty.Request, res apiResponse) (*resty.Response, error) { + return c.client.DoRequestWithResult(req, res) +} diff --git a/internal/pkg/sdk3rd/wangsu/certificate/models.go b/internal/pkg/sdk3rd/wangsu/certificate/models.go deleted file mode 100644 index 4e882e7c..00000000 --- a/internal/pkg/sdk3rd/wangsu/certificate/models.go +++ /dev/null @@ -1,52 +0,0 @@ -package certificate - -import ( - "github.com/usual2970/certimate/internal/pkg/sdk3rd/wangsu/openapi" -) - -type baseResponse struct { - RequestId *string `json:"requestId,omitempty"` - Code *string `json:"code,omitempty"` - Message *string `json:"message,omitempty"` -} - -var _ openapi.Result = (*baseResponse)(nil) - -func (r *baseResponse) SetRequestId(requestId string) { - r.RequestId = &requestId -} - -type CreateCertificateRequest struct { - Name *string `json:"name,omitempty" required:"true"` - Certificate *string `json:"certificate,omitempty" required:"true"` - PrivateKey *string `json:"privateKey,omitempty"` - Comment *string `json:"comment,omitempty" ` -} - -type CreateCertificateResponse struct { - baseResponse - CertificateUrl string `json:"location,omitempty"` -} - -type UpdateCertificateRequest struct { - Name *string `json:"name,omitempty" required:"true"` - Certificate *string `json:"certificate,omitempty"` - PrivateKey *string `json:"privateKey,omitempty"` - Comment *string `json:"comment,omitempty" ` -} - -type UpdateCertificateResponse struct { - baseResponse -} - -type ListCertificatesResponse struct { - baseResponse - Certificates []*struct { - CertificateId string `json:"certificate-id"` - Name string `json:"name"` - Comment string `json:"comment"` - ValidityFrom string `json:"certificate-validity-from"` - ValidityTo string `json:"certificate-validity-to"` - Serial string `json:"certificate-serial"` - } `json:"ssl-certificates,omitempty"` -} diff --git a/internal/pkg/sdk3rd/wangsu/certificate/types.go b/internal/pkg/sdk3rd/wangsu/certificate/types.go new file mode 100644 index 00000000..02ba6579 --- /dev/null +++ b/internal/pkg/sdk3rd/wangsu/certificate/types.go @@ -0,0 +1,38 @@ +package certificate + +type apiResponse interface { + GetCode() string + GetMessage() string +} + +type apiResponseBase struct { + Code *string `json:"code,omitempty"` + Message *string `json:"message,omitempty"` +} + +var _ apiResponse = (*apiResponseBase)(nil) + +func (r *apiResponseBase) GetCode() string { + if r.Code == nil { + return "" + } + + return *r.Code +} + +func (r *apiResponseBase) GetMessage() string { + if r.Message == nil { + return "" + } + + return *r.Message +} + +type CertificateRecord struct { + CertificateId string `json:"certificate-id"` + Name string `json:"name"` + Comment string `json:"comment"` + ValidityFrom string `json:"certificate-validity-from"` + ValidityTo string `json:"certificate-validity-to"` + Serial string `json:"certificate-serial"` +} diff --git a/internal/pkg/sdk3rd/wangsu/openapi/client.go b/internal/pkg/sdk3rd/wangsu/openapi/client.go index 09723032..4d6c50d6 100644 --- a/internal/pkg/sdk3rd/wangsu/openapi/client.go +++ b/internal/pkg/sdk3rd/wangsu/openapi/client.go @@ -23,11 +23,14 @@ type Client struct { client *resty.Client } -type Result interface { - SetRequestId(requestId string) -} +func NewClient(accessKey, secretKey string) (*Client, error) { + if accessKey == "" { + return nil, fmt.Errorf("sdkerr: unset accessKey") + } + if secretKey == "" { + return nil, fmt.Errorf("sdkerr: unset secretKey") + } -func NewClient(accessKey, secretKey string) *Client { client := resty.New(). SetBaseURL("https://open.chinanetcenter.com"). SetHeader("Accept", "application/json"). @@ -125,67 +128,64 @@ func NewClient(accessKey, secretKey string) *Client { accessKey: accessKey, secretKey: secretKey, client: client, - } + }, nil } -func (c *Client) WithTimeout(timeout time.Duration) *Client { +func (c *Client) SetTimeout(timeout time.Duration) *Client { c.client.SetTimeout(timeout) return c } -func (c *Client) sendRequest(method string, path string, params interface{}, configureReq ...func(req *resty.Request)) (*resty.Response, error) { +func (c *Client) NewRequest(method string, path string) (*resty.Request, error) { + if method == "" { + return nil, fmt.Errorf("sdkerr: unset method") + } + if path == "" { + return nil, fmt.Errorf("sdkerr: unset path") + } + req := c.client.R() - if strings.EqualFold(method, http.MethodGet) { - qs := make(map[string]string) - if params != nil { - temp := make(map[string]any) - jsonb, _ := json.Marshal(params) - json.Unmarshal(jsonb, &temp) - for k, v := range temp { - if v != nil { - qs[k] = fmt.Sprintf("%v", v) - } - } - } + req.Method = method + req.URL = path + return req, nil +} - req = req.SetQueryParams(qs) - } else { - req = req.SetHeader("Content-Type", "application/json").SetBody(params) +func (c *Client) DoRequest(req *resty.Request) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") } - if configureReq != nil { - for _, fn := range configureReq { - fn(req) - } - } + // WARN: + // PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD. - resp, err := req.Execute(method, path) + resp, err := req.Send() if err != nil { - return resp, fmt.Errorf("wangsu api error: failed to send request: %w", err) + return resp, fmt.Errorf("sdkerr: failed to send request: %w", err) } else if resp.IsError() { - return resp, fmt.Errorf("wangsu api error: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) + return resp, fmt.Errorf("sdkerr: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String()) } return resp, nil } -func (c *Client) SendRequestWithResult(method string, path string, params interface{}, result Result, configureReq ...func(req *resty.Request)) (*resty.Response, error) { - resp, err := c.sendRequest(method, path, params, configureReq...) +func (c *Client) DoRequestWithResult(req *resty.Request, res any) (*resty.Response, error) { + if req == nil { + return nil, fmt.Errorf("sdkerr: nil request") + } + + resp, err := c.DoRequest(req) if err != nil { if resp != nil { - json.Unmarshal(resp.Body(), &result) - result.SetRequestId(resp.Header().Get("X-CNC-Request-Id")) + json.Unmarshal(resp.Body(), &res) } return resp, err } - respBody := resp.Body() - if len(respBody) != 0 { - if err := json.Unmarshal(respBody, &result); err != nil { - return resp, fmt.Errorf("wangsu api error: failed to unmarshal response: %w", err) + if len(resp.Body()) != 0 { + if err := json.Unmarshal(resp.Body(), &res); err != nil { + return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w", err) } } - result.SetRequestId(resp.Header().Get("X-CNC-Request-Id")) return resp, nil }