cdn.go 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181
  1. package flexCdn
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. v1 "github.com/go-nunu/nunu-layout-advanced/api/v1"
  7. "github.com/go-nunu/nunu-layout-advanced/internal/repository/api/flexCdn"
  8. "github.com/go-nunu/nunu-layout-advanced/internal/service"
  9. "github.com/spf13/viper"
  10. "strings"
  11. )
  12. type CdnService interface {
  13. // GetToken 获取token
  14. GetToken(ctx context.Context) (string, error)
  15. // AddUser 注册用户
  16. AddUser(ctx context.Context, req v1.User) (int64, error)
  17. CreateGroup(ctx context.Context, req v1.Group) (int64, error)
  18. BindPlan(ctx context.Context, req v1.Plan) (int64, error)
  19. // 续费套餐
  20. RenewPlan(ctx context.Context, req v1.RenewalPlan) error
  21. CreateWebsite(ctx context.Context, req v1.WebsiteSend) (int64, error)
  22. EditServerType(ctx context.Context, req v1.EditWebsite, apiType string) error
  23. EditProtocol(ctx context.Context, req v1.ProxyJson, action string) error
  24. CreateOrigin(ctx context.Context, req v1.Origin) (int64, error)
  25. EditOrigin(ctx context.Context, req v1.Origin) error
  26. AddServerOrigin(ctx context.Context, serverId int64, originId int64) error
  27. EditOriginIsOn(ctx context.Context, originId int64, isOn bool) error
  28. // 修改网站基本信息
  29. EditServerBasic(ctx context.Context, serverId int64, name string,nodeId int64) error
  30. // 从网站中删除某个源站
  31. DelServerOrigin(ctx context.Context, serverId int64, originId int64) error
  32. // 删除网站
  33. DelServer(ctx context.Context, serverId int64) error
  34. // 添加ssl证书
  35. AddSSLCert(ctx context.Context, req v1.SSlCert) (int64, error)
  36. // 修改网站域名
  37. EditServerName(ctx context.Context, req v1.EditServerNames) error
  38. // 添加ssl策略
  39. AddSSLPolicy(ctx context.Context, req v1.AddSSLPolicy) (int64, error)
  40. DelSSLCert(ctx context.Context, sslCertId int64) error
  41. EditSSLCert(ctx context.Context, req v1.SSlCert) error
  42. EditSSLPolicy(ctx context.Context, req v1.SSLPolicy) error
  43. // 修改反向代理
  44. EditProxy(ctx context.Context, req v1.Proxy) error
  45. // 修改日志
  46. EditWebLog(ctx context.Context,webId int64, req v1.WebLog) error
  47. // 修改CC配置
  48. EditCcConfig(ctx context.Context,webId int64, req v1.CcConfig) error
  49. // 添加webSocket
  50. AddWebSockets(ctx context.Context, req v1.WebSocket) (int64,error)
  51. // 修改webSocket
  52. EditWebSockets(ctx context.Context, req v1.WebSocket) error
  53. // 启用webSocket
  54. EditHTTPWebWebsocket(ctx context.Context,websocketId int64,websocketJSON []byte) error
  55. // 启用/禁用网站
  56. EditWebIsOn(ctx context.Context,serverId int64,isOn bool) error
  57. // 删除已购套餐
  58. DelUserPlan(ctx context.Context,planId int64) error
  59. // 删除网站分组
  60. DelServerGroup(ctx context.Context,serverId int64) error
  61. // 删除IP
  62. DelIpItem(ctx context.Context,ipitemId int64,value string,ipFrom string,ipTo string,ipListId int64) error
  63. // 创建空防火墙策略
  64. AddWafPolicy(ctx context.Context,req v1.AddWafPolicy) (int64, error)
  65. // 更改防火墙设置
  66. EditHTTPWebFirewal(ctx context.Context,httpWebId int64,FirewallJSON v1.Firewall) error
  67. // 创建IP列表
  68. AddIPList(ctx context.Context, req v1.IPListRequest) (int64, error)
  69. // 添加IP
  70. AddIpItem(ctx context.Context, req v1.AddIpItem) error
  71. // 修改IP
  72. EditIpItem(ctx context.Context, req v1.AddIpItem) error
  73. }
  74. func NewCdnService(
  75. service *service.Service,
  76. conf *viper.Viper,
  77. request service.RequestService,
  78. cdnRepository flexCdn.CdnRepository,
  79. ) CdnService {
  80. return &cdnService{
  81. Service: service,
  82. Url: conf.GetString("flexCdn.Url"),
  83. AccessKeyID: conf.GetString("flexCdn.AccessKeyID"),
  84. AccessKeySecret: conf.GetString("flexCdn.AccessKeySecret"),
  85. request: request,
  86. cdnRepository: cdnRepository,
  87. maxRetryCount: 3, // 可以配置最大重试次数
  88. retryDelaySeconds: 2, // 可以配置重试间隔
  89. }
  90. }
  91. type cdnService struct {
  92. *service.Service
  93. Url string
  94. AccessKeyID string
  95. AccessKeySecret string
  96. request service.RequestService
  97. cdnRepository flexCdn.CdnRepository
  98. maxRetryCount int
  99. retryDelaySeconds int
  100. }
  101. // SendData 是一个通用的请求发送方法,它封装了 token 过期重试的逻辑
  102. func (s *cdnService) sendDataWithTokenRetry(ctx context.Context, formData map[string]interface{}, apiUrl string) ([]byte, error) {
  103. var resBody []byte
  104. for i := 0; i < s.maxRetryCount; i++ {
  105. token, err := s.Token(ctx) // 确保使用最新的 token
  106. if err != nil {
  107. return nil, fmt.Errorf("获取或刷新 token 失败: %w", err)
  108. }
  109. resBody, err = s.request.Request(ctx, formData, apiUrl, "X-Cloud-Access-Token", token)
  110. if err != nil {
  111. // 检查错误是否是由于 token 无效引起的
  112. if s.isTokenInvalidError(resBody, err) { // 判断是否是 token 无效错误
  113. _, getTokenErr := s.GetToken(ctx)
  114. if getTokenErr != nil {
  115. return nil, fmt.Errorf("刷新 token 失败: %w", getTokenErr)
  116. }
  117. continue // 继续下一次循环,使用新的 token
  118. }
  119. return nil, fmt.Errorf("请求失败: %w", err)
  120. }
  121. // 成功获取到响应,处理响应体
  122. var generalResponse v1.GeneralResponse[any]
  123. if err := json.Unmarshal(resBody, &generalResponse); err != nil {
  124. return nil, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  125. }
  126. // 检查 API 返回的 code 和 message
  127. if generalResponse.Code == 400 && generalResponse.Message == "invalid access token" {
  128. fmt.Printf("尝试 %d/%d:API 返回无效 token 错误,准备刷新并重试...\n", i+1, s.maxRetryCount)
  129. _, getTokenErr := s.GetToken(ctx)
  130. if getTokenErr != nil {
  131. return nil, fmt.Errorf("刷新 token 失败: %w", getTokenErr)
  132. }
  133. continue // 继续下一次循环,使用新的 token
  134. }
  135. // 成功处理,返回结果
  136. return resBody, nil
  137. }
  138. // 如果循环结束仍未成功,则返回最终错误
  139. return nil, fmt.Errorf("达到最大重试次数后请求仍然失败")
  140. }
  141. // isTokenInvalidError 是一个辅助函数,用于判断错误是否是由于 token 无效引起的。
  142. // 你需要根据你的 request.Request 实现来具体实现这个函数。
  143. // 例如,你可以检查 resBody 是否包含特定的错误信息。
  144. func (s *cdnService) isTokenInvalidError(resBody []byte, err error) bool {
  145. // 示例:如果请求本身就返回了非 200 的错误,并且响应体中有特定信息
  146. if err != nil {
  147. // 尝试从 resBody 中解析出错误信息,判断是否是 token 无效
  148. var generalResponse v1.GeneralResponse[any]
  149. if parseErr := json.Unmarshal(resBody, &generalResponse); parseErr == nil {
  150. if generalResponse.Code == 400 && generalResponse.Message == "invalid access token" {
  151. return true
  152. }
  153. }
  154. // 或者检查 err 本身是否有相关的错误信息
  155. // if strings.Contains(err.Error(), "invalid access token") {
  156. // return true
  157. // }
  158. }
  159. return false
  160. }
  161. func (s *cdnService) GetToken(ctx context.Context) (string, error) {
  162. formData := map[string]interface{}{
  163. "type": "admin",
  164. "accessKeyId": s.AccessKeyID,
  165. "accessKey": s.AccessKeySecret,
  166. }
  167. apiUrl := s.Url + "APIAccessTokenService/getAPIAccessToken"
  168. resBody, err := s.request.Request(ctx, formData, apiUrl, "X-Cloud-Access-Token", "")
  169. if err != nil {
  170. return "", err
  171. }
  172. var res v1.GeneralResponse[v1.FlexCdnTokenResponse]
  173. if err := json.Unmarshal(resBody, &res); err != nil {
  174. return "", fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  175. }
  176. if res.Code != 200 {
  177. return "", fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  178. }
  179. err = s.cdnRepository.PutToken(ctx, res.Data.Token)
  180. if err != nil {
  181. return "", err
  182. }
  183. return res.Data.Token, nil
  184. }
  185. func (s *cdnService) Token(ctx context.Context) (string, error) {
  186. token, err := s.cdnRepository.GetToken(ctx)
  187. if err != nil {
  188. return "", err
  189. }
  190. if token == "" {
  191. token, err = s.GetToken(ctx)
  192. if err != nil {
  193. return "", err
  194. }
  195. }
  196. return token, nil
  197. }
  198. // 注册用户
  199. func (s *cdnService) AddUser(ctx context.Context, req v1.User) (int64, error) {
  200. formData := map[string]interface{}{
  201. "id": req.ID,
  202. "username": req.Username,
  203. "password": "a7fKiKujgAzzsJ6", // 这个密码应该被妥善管理,而不是硬编码
  204. "fullname": req.Fullname,
  205. "mobile": req.Mobile,
  206. "tel": req.Tel,
  207. "email": req.Email,
  208. "remark": req.Remark,
  209. "source": req.Source,
  210. "nodeClusterId": 2,
  211. }
  212. apiUrl := s.Url + "UserService/createUser"
  213. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  214. if err != nil {
  215. return 0, err
  216. }
  217. type DataStr struct {
  218. UserId int64 `json:"userId" form:"userId"`
  219. }
  220. var res v1.GeneralResponse[DataStr]
  221. if err := json.Unmarshal(resBody, &res); err != nil {
  222. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  223. }
  224. if res.Code != 200 {
  225. return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  226. }
  227. if res.Data.UserId == 0 {
  228. return 0, fmt.Errorf("添加用户失败")
  229. }
  230. return res.Data.UserId, nil
  231. }
  232. // 创建规则分组
  233. func (s *cdnService) CreateGroup(ctx context.Context, req v1.Group) (int64, error) {
  234. formData := map[string]interface{}{
  235. "name": req.Name,
  236. }
  237. apiUrl := s.Url + "ServerGroupService/createServerGroup"
  238. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl) // 使用封装后的方法
  239. if err != nil {
  240. return 0, err
  241. }
  242. type DataStr struct {
  243. ServerGroupId int64 `json:"serverGroupId" form:"serverGroupId"`
  244. }
  245. var res v1.GeneralResponse[DataStr]
  246. if err := json.Unmarshal(resBody, &res); err != nil {
  247. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  248. }
  249. if res.Code != 200 {
  250. return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  251. }
  252. if res.Data.ServerGroupId == 0 {
  253. return 0, fmt.Errorf("创建规则分组失败")
  254. }
  255. return res.Data.ServerGroupId, nil
  256. }
  257. // 分配套餐
  258. func (s *cdnService) BindPlan(ctx context.Context, req v1.Plan) (int64, error) {
  259. formData := map[string]interface{}{
  260. "userId": req.UserId,
  261. "planId": req.PlanId,
  262. "dayTo": req.DayTo,
  263. "period": req.Period,
  264. "countPeriod": req.CountPeriod,
  265. "name": req.Name,
  266. "isFree": req.IsFree,
  267. "periodDayTo": req.PeriodDayTo,
  268. }
  269. apiUrl := s.Url + "UserPlanService/buyUserPlan"
  270. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl) // 使用封装后的方法
  271. if err != nil {
  272. return 0, err
  273. }
  274. type DataStr struct {
  275. UserPlanId int64 `json:"userPlanId" form:"userPlanId"`
  276. }
  277. var res v1.GeneralResponse[DataStr]
  278. if err := json.Unmarshal(resBody, &res); err != nil {
  279. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  280. }
  281. if res.Code != 200 {
  282. return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  283. }
  284. if res.Data.UserPlanId == 0 {
  285. return 0, fmt.Errorf("分配套餐失败")
  286. }
  287. return res.Data.UserPlanId, nil
  288. }
  289. // 续费套餐
  290. func (s *cdnService) RenewPlan(ctx context.Context, req v1.RenewalPlan) error {
  291. formData := map[string]interface{}{
  292. "userPlanId": req.UserPlanId,
  293. "dayTo": req.DayTo,
  294. "period": req.Period,
  295. "countPeriod": req.CountPeriod,
  296. "isFree": req.IsFree,
  297. "periodDayTo": req.PeriodDayTo,
  298. }
  299. apiUrl := s.Url + "UserPlanService/renewUserPlan"
  300. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl) // 使用封装后的方法
  301. if err != nil {
  302. return err
  303. }
  304. var res v1.GeneralResponse[any]
  305. if err := json.Unmarshal(resBody, &res); err != nil {
  306. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  307. }
  308. if res.Code != 200 {
  309. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  310. }
  311. return nil
  312. }
  313. // 创建网站
  314. func (s *cdnService) CreateWebsite(ctx context.Context, req v1.WebsiteSend) (int64, error) {
  315. formData := map[string]interface{}{
  316. "userId": req.UserId,
  317. "type": req.Type,
  318. "name": req.Name,
  319. "description": req.Description,
  320. "serverNamesJSON": req.ServerNamesJSON,
  321. "httpJSON": req.HttpJSON,
  322. "httpsJSON": req.HttpsJSON,
  323. "tcpJSON": req.TcpJSON,
  324. "tlsJSON": req.TlsJSON,
  325. "udpJSON": req.UdpJSON,
  326. "webId": req.WebId,
  327. "reverseProxyJSON": req.ReverseProxyJSON,
  328. "serverGroupIds": req.ServerGroupIds,
  329. "userPlanId": req.UserPlanId,
  330. "nodeClusterId": req.NodeClusterId,
  331. }
  332. apiUrl := s.Url + "ServerService/createServer"
  333. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl) // 使用封装后的方法
  334. if err != nil {
  335. return 0, err
  336. }
  337. type DataStr struct {
  338. ServerId int64 `json:"serverId" form:"serverId"`
  339. }
  340. var res v1.GeneralResponse[DataStr]
  341. if err := json.Unmarshal(resBody, &res); err != nil {
  342. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  343. }
  344. if res.Code != 200 {
  345. return 0, fmt.Errorf("创建网站API 错误: code %d, msg '%s'", res.Code, res.Message)
  346. }
  347. if res.Data.ServerId == 0 {
  348. return 0, fmt.Errorf("创建网站失败")
  349. }
  350. return res.Data.ServerId, nil
  351. }
  352. func (s *cdnService) EditProtocol(ctx context.Context, req v1.ProxyJson, action string) error {
  353. formData := map[string]interface{}{
  354. "serverId": req.ServerId,
  355. }
  356. var apiUrl string
  357. switch action {
  358. case "tcp":
  359. formData["tcpJSON"] = req.JSON
  360. apiUrl = s.Url + "ServerService/updateServerTCP"
  361. case "tls":
  362. formData["tlsJSON"] = req.JSON
  363. apiUrl = s.Url + "ServerService/updateServerTLS"
  364. case "udp":
  365. formData["udpJSON"] = req.JSON
  366. apiUrl = s.Url + "ServerService/updateServerUDP"
  367. case "http":
  368. formData["httpJSON"] = req.JSON
  369. apiUrl = s.Url + "ServerService/updateServerHTTP"
  370. case "https":
  371. formData["httpsJSON"] = req.JSON
  372. apiUrl = s.Url + "ServerService/updateServerHTTPS"
  373. default:
  374. return fmt.Errorf("不支持的协议类型")
  375. }
  376. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl) // 使用封装后的方法
  377. if err != nil {
  378. return err
  379. }
  380. var res v1.GeneralResponse[any]
  381. if err := json.Unmarshal(resBody, &res); err != nil {
  382. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  383. }
  384. if res.Code != 200 {
  385. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  386. }
  387. return nil
  388. }
  389. func (s *cdnService) CreateOrigin(ctx context.Context, req v1.Origin) (int64, error) {
  390. formData := map[string]interface{}{
  391. "name": req.Name,
  392. "addr": req.Addr,
  393. "ossJSON": req.OssJSON,
  394. "description": req.Description,
  395. "weight": req.Weight,
  396. "isOn": req.IsOn,
  397. "domains": req.Domains,
  398. "certRefJSON": req.CertRefJSON,
  399. "host": req.Host,
  400. "followPort": req.FollowPort,
  401. "http2Enabled": req.Http2Enabled,
  402. "tlsSecurityVerifyMode": req.TlsSecurityVerifyMode,
  403. }
  404. apiUrl := s.Url + "OriginService/createOrigin"
  405. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl) // 使用封装后的方法
  406. if err != nil {
  407. return 0, err
  408. }
  409. type DataStr struct {
  410. OriginId int64 `json:"originId" form:"originId"`
  411. }
  412. var res v1.GeneralResponse[DataStr]
  413. if err := json.Unmarshal(resBody, &res); err != nil {
  414. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  415. }
  416. if res.Code != 200 {
  417. return 0, fmt.Errorf("添加源站API 错误: code %d, msg '%s'", res.Code, res.Message)
  418. }
  419. if res.Data.OriginId == 0 {
  420. return 0, fmt.Errorf("创建源站失败")
  421. }
  422. return res.Data.OriginId, nil
  423. }
  424. func (s *cdnService) EditServerType(ctx context.Context, req v1.EditWebsite, apiType string) error {
  425. typeName := apiType + "JSON"
  426. formData := map[string]interface{}{
  427. "serverId": req.Id,
  428. typeName: req.TypeJSON,
  429. }
  430. apiUrl := s.Url + "ServerService/updateServer" + strings.ToUpper(apiType)
  431. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  432. if err != nil {
  433. return err
  434. }
  435. var res v1.GeneralResponse[any]
  436. if err := json.Unmarshal(resBody, &res); err != nil {
  437. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  438. }
  439. if res.Code != 200 {
  440. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  441. }
  442. return nil
  443. }
  444. // EditOrigin 编辑源站
  445. func (s *cdnService) EditOrigin(ctx context.Context, req v1.Origin) error {
  446. formData := map[string]interface{}{
  447. "originId": req.OriginId,
  448. "name": req.Name,
  449. "addr": req.Addr,
  450. "ossJSON": req.OssJSON,
  451. "description": req.Description,
  452. "weight": req.Weight,
  453. "isOn": req.IsOn,
  454. "domains": req.Domains,
  455. "certRefJSON": req.CertRefJSON,
  456. "host": req.Host,
  457. "followPort": req.FollowPort,
  458. "http2Enabled": req.Http2Enabled,
  459. "tlsSecurityVerifyMode": req.TlsSecurityVerifyMode,
  460. }
  461. apiUrl := s.Url + "OriginService/updateOrigin"
  462. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl) // 使用封装后的方法
  463. if err != nil {
  464. return err
  465. }
  466. var res v1.GeneralResponse[any]
  467. if err := json.Unmarshal(resBody, &res); err != nil {
  468. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  469. }
  470. if res.Code != 200 {
  471. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  472. }
  473. return nil
  474. }
  475. // AddServerOrigin 网站绑定源站
  476. func (s *cdnService) AddServerOrigin(ctx context.Context, serverId int64, originId int64) error {
  477. formData := map[string]interface{}{
  478. "serverId": serverId,
  479. "originId": originId,
  480. "isPrimary": true,
  481. }
  482. apiUrl := s.Url + "ServerService/addServerOrigin"
  483. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  484. if err != nil {
  485. return err
  486. }
  487. var res v1.GeneralResponse[any]
  488. if err := json.Unmarshal(resBody, &res); err != nil {
  489. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  490. }
  491. if res.Code != 200 {
  492. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  493. }
  494. return nil
  495. }
  496. // EditOriginIsOn 编辑源站是否开启
  497. func (s *cdnService) EditOriginIsOn(ctx context.Context, originId int64, isOn bool) error {
  498. formData := map[string]interface{}{
  499. "originId": originId,
  500. "isOn": isOn,
  501. }
  502. apiUrl := s.Url + "OriginService/updateOriginIsOn"
  503. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  504. if err != nil {
  505. return err
  506. }
  507. var res v1.GeneralResponse[any]
  508. if err := json.Unmarshal(resBody, &res); err != nil {
  509. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  510. }
  511. if res.Code != 200 {
  512. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  513. }
  514. return nil
  515. }
  516. // EditServerBasic 修改网站基本信息
  517. func (s *cdnService) EditServerBasic(ctx context.Context, serverId int64, name string,nodeId int64) error {
  518. formData := map[string]interface{}{
  519. "serverId": serverId,
  520. "name": name,
  521. "nodeClusterId": nodeId,
  522. "isOn": true,
  523. }
  524. apiUrl := s.Url + "ServerService/updateServerBasic"
  525. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  526. if err != nil {
  527. return err
  528. }
  529. var res v1.GeneralResponse[any]
  530. if err := json.Unmarshal(resBody, &res); err != nil {
  531. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  532. }
  533. if res.Code != 200 {
  534. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  535. }
  536. return nil
  537. }
  538. // DelServerOrigin 从网站中删除某个源站
  539. func (s *cdnService) DelServerOrigin(ctx context.Context, serverId int64, originId int64) error {
  540. formData := map[string]interface{}{
  541. "serverId": serverId,
  542. "originId": originId,
  543. }
  544. apiUrl := s.Url + "ServerService/deleteServerOrigin"
  545. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  546. if err != nil {
  547. return err
  548. }
  549. var res v1.GeneralResponse[any]
  550. if err := json.Unmarshal(resBody, &res); err != nil {
  551. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  552. }
  553. if res.Code != 200 {
  554. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  555. }
  556. return nil
  557. }
  558. func (s *cdnService) DelServer(ctx context.Context, serverId int64) error {
  559. formData := map[string]interface{}{
  560. "serverId": serverId,
  561. }
  562. apiUrl := s.Url + "ServerService/deleteServer"
  563. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  564. if err != nil {
  565. return err
  566. }
  567. var res v1.GeneralResponse[any]
  568. if err := json.Unmarshal(resBody, &res); err != nil {
  569. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  570. }
  571. if res.Code != 200 {
  572. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  573. }
  574. return nil
  575. }
  576. // AddSSLCert 添加证书
  577. func (s *cdnService) AddSSLCert(ctx context.Context, req v1.SSlCert) (int64, error) {
  578. formData := map[string]interface{}{
  579. "isOn": req.IsOn,
  580. "userId": req.UserId,
  581. "name": req.Name,
  582. "serverName": req.ServerName,
  583. "description": req.Description,
  584. "isCA": req.IsCA,
  585. "certData": req.CertData,
  586. "keyData": req.KeyData,
  587. "timeBeginAt": req.TimeBeginAt,
  588. "timeEndAt": req.TimeEndAt,
  589. "dnsNames": req.DnsNames,
  590. "commonNames": req.CommonNames,
  591. "isSelfSigned": req.IsSelfSigned,
  592. }
  593. apiUrl := s.Url + "SSLCertService/createSSLCert"
  594. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  595. if err != nil {
  596. return 0, err
  597. }
  598. type DataStr struct {
  599. SslCertId int64 `json:"sslCertId" form:"sslCertId"`
  600. }
  601. var res v1.GeneralResponse[DataStr]
  602. if err := json.Unmarshal(resBody, &res); err != nil {
  603. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  604. }
  605. if res.Code != 200 {
  606. return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  607. }
  608. return res.Data.SslCertId, nil
  609. }
  610. // 修改网站域名
  611. func (s *cdnService) EditServerName(ctx context.Context, req v1.EditServerNames) error {
  612. formData := map[string]interface{}{
  613. "serverId": req.ServerId,
  614. "serverNamesJSON": req.ServerNamesJSON,
  615. }
  616. apiUrl := s.Url + "ServerService/updateServerNames"
  617. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  618. if err != nil {
  619. return err
  620. }
  621. var res v1.GeneralResponse[any]
  622. if err := json.Unmarshal(resBody, &res); err != nil {
  623. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  624. }
  625. if res.Code != 200 {
  626. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  627. }
  628. return nil
  629. }
  630. // 添加ssl策略
  631. func (s *cdnService) AddSSLPolicy(ctx context.Context, req v1.AddSSLPolicy) (int64, error) {
  632. formData := map[string]interface{}{
  633. "http2Enabled": req.Http2Enabled,
  634. "http3Enabled": req.Http3Enabled,
  635. "minVersion": req.MinVersion,
  636. "sslCertsJSON": req.SslCertsJSON,
  637. "hstsJSON": req.HstsJSON,
  638. "clientAuthType": req.ClientAuthType,
  639. "cipherSuites": req.CipherSuites,
  640. "cipherSuitesIsOn": req.CipherSuitesIsOn,
  641. "ocspIsOn": req.OcspIsOn,
  642. }
  643. apiUrl := s.Url + "SSLPolicyService/createSSLPolicy"
  644. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  645. if err != nil {
  646. return 0, err
  647. }
  648. type DataStr struct {
  649. SslPolicyId int64 `json:"sslPolicyId" form:"sslPolicyId"`
  650. }
  651. var res v1.GeneralResponse[DataStr]
  652. if err := json.Unmarshal(resBody, &res); err != nil {
  653. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  654. }
  655. if res.Code != 200 {
  656. return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  657. }
  658. return res.Data.SslPolicyId, nil
  659. }
  660. func (s *cdnService) DelSSLCert(ctx context.Context, sslCertId int64) error {
  661. formData := map[string]interface{}{
  662. "sslCertId": sslCertId,
  663. }
  664. apiUrl := s.Url + "SSLCertService/deleteSSLCert"
  665. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  666. if err != nil {
  667. return err
  668. }
  669. var res v1.GeneralResponse[any]
  670. if err := json.Unmarshal(resBody, &res); err != nil {
  671. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  672. }
  673. if res.Code != 200 {
  674. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  675. }
  676. return nil
  677. }
  678. func (s *cdnService) GetSSLPolicy(ctx context.Context, sslPolicyId int64) (v1.SSLPolicy, error) {
  679. formData := map[string]interface{}{
  680. "sslPolicyId": sslPolicyId,
  681. "ignoreData": true,
  682. }
  683. apiUrl := s.Url + "SSLPolicyService/findEnabledSSLPolicyConfig"
  684. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  685. if err != nil {
  686. return v1.SSLPolicy{}, err
  687. }
  688. var res v1.GeneralResponse[v1.SSLPolicy]
  689. if err := json.Unmarshal(resBody, &res); err != nil {
  690. return v1.SSLPolicy{}, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  691. }
  692. if res.Code != 200 {
  693. return v1.SSLPolicy{}, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  694. }
  695. return res.Data, nil
  696. }
  697. func (s *cdnService) EditSSLCert(ctx context.Context, req v1.SSlCert) error {
  698. formData := map[string]interface{}{
  699. "sslCertId": req.SslCertId,
  700. "userId": req.UserId,
  701. "isOn": req.IsOn,
  702. "name": req.Name,
  703. "description": req.Description,
  704. "isCA": req.IsCA,
  705. "certData": req.CertData,
  706. "keyData": req.KeyData,
  707. "timeBeginAt": req.TimeBeginAt,
  708. "timeEndAt": req.TimeEndAt,
  709. "dnsNames": req.DnsNames,
  710. "commonNames": req.CommonNames,
  711. "isSelfSigned": req.IsSelfSigned,
  712. }
  713. apiUrl := s.Url + "SSLCertService/updateSSLCert"
  714. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  715. if err != nil {
  716. return err
  717. }
  718. var res v1.GeneralResponse[any]
  719. if err := json.Unmarshal(resBody, &res); err != nil {
  720. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  721. }
  722. if res.Code != 200 {
  723. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  724. }
  725. return nil
  726. }
  727. func (s *cdnService) EditSSLPolicy(ctx context.Context, req v1.SSLPolicy) error {
  728. formData := map[string]interface{}{
  729. "sslPolicyId": req.SslPolicyId,
  730. "http2Enabled": req.Http2Enabled,
  731. "http3Enabled": req.Http3Enabled,
  732. "minVersion": req.MinVersion,
  733. "sslCertsJSON": req.SslCertsJSON,
  734. "hstsJSON": req.HstsJSON,
  735. "clientAuthType": req.ClientAuthType,
  736. "cipherSuites": req.CipherSuites,
  737. "cipherSuitesIsOn": req.CipherSuitesIsOn,
  738. }
  739. apiUrl := s.Url + "SSLPolicyService/updateSSLPolicy"
  740. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  741. if err != nil {
  742. return err
  743. }
  744. var res v1.GeneralResponse[any]
  745. if err := json.Unmarshal(resBody, &res); err != nil {
  746. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  747. }
  748. if res.Code != 200 {
  749. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  750. }
  751. return nil
  752. }
  753. // 修改反向代理
  754. func (s *cdnService) EditProxy(ctx context.Context, req v1.Proxy) error {
  755. formData := map[string]interface{}{
  756. "reverseProxyId" : req.ReverseProxyId,
  757. "requestHostType" : req.RequestHostType,
  758. "requestHost" : req.RequestHost,
  759. "requestHostExcludingPort" : req.RequestHostExcludingPort,
  760. "requestURI" : req.RequestURI,
  761. "stripPrefix" : req.StripPrefix,
  762. "autoFlush" : req.AutoFlush,
  763. "addHeaders" : req.AddHeaders,
  764. "proxyProtocolJSON": req.ProxyProtocolJSON,
  765. "followRedirects" : req.FollowRedirects,
  766. "retry50X" : req.Retry50X,
  767. "retry40X" : req.Retry40X,
  768. }
  769. apiUrl := s.Url + "ReverseProxyService/updateReverseProxy"
  770. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  771. if err != nil {
  772. return err
  773. }
  774. var res v1.GeneralResponse[any]
  775. if err := json.Unmarshal(resBody, &res); err != nil {
  776. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  777. }
  778. if res.Code != 200 {
  779. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  780. }
  781. return nil
  782. }
  783. // 修改网站日志配置
  784. func (s *cdnService) EditWebLog(ctx context.Context,webId int64, req v1.WebLog) error {
  785. reqJson, err := json.Marshal(req)
  786. if err != nil {
  787. return err
  788. }
  789. formData := map[string]interface{}{
  790. "httpWebId": webId,
  791. "accessLogJSON": reqJson,
  792. }
  793. apiUrl := s.Url + "HTTPWebService/updateHTTPWebAccessLog"
  794. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  795. if err != nil {
  796. return err
  797. }
  798. var res v1.GeneralResponse[any]
  799. if err := json.Unmarshal(resBody, &res); err != nil {
  800. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  801. }
  802. if res.Code != 200 {
  803. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  804. }
  805. return nil
  806. }
  807. // 修改网站CC配置
  808. func (s *cdnService) EditCcConfig(ctx context.Context,webId int64, req v1.CcConfig) error {
  809. reqJson, err := json.Marshal(req)
  810. if err != nil {
  811. return err
  812. }
  813. formData := map[string]interface{}{
  814. "httpWebId": webId,
  815. "ccJSON": reqJson,
  816. }
  817. apiUrl := s.Url + "HTTPWebService/updateHTTPWebCC"
  818. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  819. if err != nil {
  820. return err
  821. }
  822. var res v1.GeneralResponse[any]
  823. if err := json.Unmarshal(resBody, &res); err != nil {
  824. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  825. }
  826. if res.Code != 200 {
  827. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  828. }
  829. return nil
  830. }
  831. // 创建websockets配置
  832. func (s *cdnService) AddWebSockets(ctx context.Context, req v1.WebSocket) (int64,error) {
  833. formData := map[string]interface{}{
  834. "handshakeTimeoutJSON": req.HandshakeTimeoutJSON,
  835. "allowAllOrigins" : req.AllowAllOrigins,
  836. "allowedOrigins" : req.AllowedOrigins,
  837. "requestSameOrigin" : req.RequestSameOrigin,
  838. "requestOrigin" : req.RequestOrigin,
  839. }
  840. apiUrl := s.Url + "HTTPWebsocketService/createHTTPWebsocket"
  841. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  842. if err != nil {
  843. return 0,err
  844. }
  845. type WebSocket struct {
  846. WebSocketId int64 `json:"websocketId"`
  847. }
  848. var res v1.GeneralResponse[WebSocket]
  849. if err := json.Unmarshal(resBody, &res); err != nil {
  850. return 0,fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  851. }
  852. if res.Code != 200 {
  853. return 0,fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  854. }
  855. return res.Data.WebSocketId,nil
  856. }
  857. func (s *cdnService) EditWebSockets(ctx context.Context,req v1.WebSocket) error {
  858. formData := map[string]interface{}{
  859. "websocketId" : req.WebsocketId,
  860. "handshakeTimeoutJSON": req.HandshakeTimeoutJSON,
  861. "allowAllOrigins" : req.AllowAllOrigins,
  862. "allowedOrigins" : req.AllowedOrigins,
  863. "requestSameOrigin" : req.RequestSameOrigin,
  864. "requestOrigin" : req.RequestOrigin,
  865. }
  866. apiUrl := s.Url + "HTTPWebsocketService/updateHTTPWebsocket"
  867. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  868. if err != nil {
  869. return err
  870. }
  871. var res v1.GeneralResponse[any]
  872. if err := json.Unmarshal(resBody, &res); err != nil {
  873. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  874. }
  875. if res.Code != 200 {
  876. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  877. }
  878. return nil
  879. }
  880. // 启用/禁用websockets
  881. func (s *cdnService) EditHTTPWebWebsocket(ctx context.Context,websocketId int64,websocketJSON []byte) error {
  882. formData := map[string]interface{}{
  883. "httpWebId" : websocketId,
  884. "websocketJSON": websocketJSON,
  885. }
  886. apiUrl := s.Url + "HTTPWebService/updateHTTPWebWebsocket"
  887. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  888. if err != nil {
  889. return err
  890. }
  891. var res v1.GeneralResponse[any]
  892. if err := json.Unmarshal(resBody, &res); err != nil {
  893. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  894. }
  895. if res.Code != 200 {
  896. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  897. }
  898. return nil
  899. }
  900. // 启用/禁用网站
  901. func (s *cdnService) EditWebIsOn(ctx context.Context,serverId int64,isOn bool) error {
  902. formData := map[string]interface{}{
  903. "serverId": serverId,
  904. "isOn": isOn,
  905. }
  906. apiUrl := s.Url + "ServerService/updateServerIsOn"
  907. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  908. if err != nil {
  909. return err
  910. }
  911. var res v1.GeneralResponse[any]
  912. if err := json.Unmarshal(resBody, &res); err != nil {
  913. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  914. }
  915. if res.Code != 200 {
  916. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  917. }
  918. return nil
  919. }
  920. // 删除已购套餐
  921. func (s *cdnService) DelUserPlan(ctx context.Context,planId int64) error {
  922. formData := map[string]interface{}{
  923. "userPlanId": planId,
  924. }
  925. apiUrl := s.Url + "UserPlanService/deleteUserPlan"
  926. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  927. if err != nil {
  928. return err
  929. }
  930. var res v1.GeneralResponse[any]
  931. if err := json.Unmarshal(resBody, &res); err != nil {
  932. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  933. }
  934. if res.Code != 200 {
  935. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  936. }
  937. return nil
  938. }
  939. // 删除网站分组
  940. func (s *cdnService) DelServerGroup(ctx context.Context,serverId int64) error {
  941. formData := map[string]interface{}{
  942. "serverId": serverId,
  943. }
  944. apiUrl := s.Url + "ServerService/deleteServer"
  945. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  946. if err != nil {
  947. return err
  948. }
  949. var res v1.GeneralResponse[any]
  950. if err := json.Unmarshal(resBody, &res); err != nil {
  951. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  952. }
  953. if res.Code != 200 {
  954. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  955. }
  956. return nil
  957. }
  958. // 删除IP
  959. func (s *cdnService) DelIpItem(ctx context.Context,ipitemId int64,value string,ipFrom string,ipTo string,ipListId int64) error {
  960. formData := map[string]interface{}{
  961. "ipitemId": ipitemId,
  962. "value": value,
  963. "ipFrom": ipFrom,
  964. "ipTo": ipTo,
  965. "ipListId": ipListId,
  966. }
  967. apiUrl := s.Url + "IPItemService/deleteIPItem"
  968. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  969. if err != nil {
  970. return err
  971. }
  972. var res v1.GeneralResponse[any]
  973. if err := json.Unmarshal(resBody, &res); err != nil {
  974. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  975. }
  976. if res.Code != 200 {
  977. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  978. }
  979. return nil
  980. }
  981. // 创建空防火墙策略
  982. func (s *cdnService) AddWafPolicy(ctx context.Context,req v1.AddWafPolicy) (int64, error) {
  983. formData := map[string]interface{}{
  984. "isOn": req.IsOn,
  985. "name" : req.Name,
  986. "description" : req.Description,
  987. "serverId" : req.ServerId,
  988. "serverGroupId" : req.ServerGroupId,
  989. }
  990. apiUrl := s.Url + "HTTPFirewallPolicyService/createEmptyHTTPFirewallPolicy"
  991. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  992. if err != nil {
  993. return 0, err
  994. }
  995. var res v1.GeneralResponse[map[string]int64]
  996. if err := json.Unmarshal(resBody, &res); err != nil {
  997. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  998. }
  999. if res.Code != 200 {
  1000. return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  1001. }
  1002. if res.Data["httpFirewallPolicyId"] == 0 {
  1003. return 0, fmt.Errorf("创建空防火墙策略失败")
  1004. }
  1005. return res.Data["httpFirewallPolicyId"], nil
  1006. }
  1007. // 更改防火墙设置
  1008. func (s *cdnService) EditHTTPWebFirewal(ctx context.Context,httpWebId int64,FirewallJSON v1.Firewall) error {
  1009. frireWallJson,err := json.Marshal(FirewallJSON)
  1010. if err != nil {
  1011. return err
  1012. }
  1013. formData := map[string]interface{}{
  1014. "httpWebId" : httpWebId,
  1015. "firewallJSON" : frireWallJson,
  1016. }
  1017. apiUrl := s.Url + "HTTPWebService/updateHTTPWebFirewall"
  1018. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  1019. if err != nil {
  1020. return err
  1021. }
  1022. var res v1.GeneralResponse[any]
  1023. if err := json.Unmarshal(resBody, &res); err != nil {
  1024. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  1025. }
  1026. if res.Code != 200 {
  1027. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  1028. }
  1029. return nil
  1030. }
  1031. // 创建IP列表
  1032. func (s *cdnService) AddIPList(ctx context.Context, req v1.IPListRequest) (int64, error) {
  1033. formData := map[string]interface{}{
  1034. "type": req.Type,
  1035. "name": req.Name,
  1036. "code": req.Code,
  1037. "timeoutJSON": req.TimeoutJSON,
  1038. "isPublic": req.IsPublic,
  1039. "description": req.Description,
  1040. "isGlobal": req.IsGlobal,
  1041. "serverId": req.ServerId,
  1042. }
  1043. apiUrl := s.Url + "IPListService/createIPList"
  1044. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  1045. if err != nil {
  1046. return 0, err
  1047. }
  1048. var res v1.GeneralResponse[int64]
  1049. if err := json.Unmarshal(resBody, &res); err != nil {
  1050. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  1051. }
  1052. if res.Code != 200 {
  1053. return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  1054. }
  1055. return res.Data, nil
  1056. }
  1057. // 创建IP
  1058. func (s *cdnService) AddIpItem(ctx context.Context, req v1.AddIpItem) error {
  1059. formData := map[string]interface{}{
  1060. "ipListId": req.IpListId,
  1061. "value": req.Value,
  1062. "ipFrom": req.IpFrom,
  1063. "ipTo": req.IpTo,
  1064. "expiredAt": req.ExpiredAt,
  1065. "reason": req.Reason,
  1066. "type": req.Type,
  1067. "eventLevel": req.EventLevel,
  1068. "nodeId": req.NodeId,
  1069. "serverId": req.ServerId,
  1070. "sourceNodeId": req.SourceNodeId,
  1071. "sourceServerId": req.SourceServerId,
  1072. "sourceHTTPFirewallPolicyId": req.SourceHTTPFirewallPolicyId,
  1073. "sourceHTTPFirewallRuleGroupId": req.SourceHTTPFirewallRuleGroupId,
  1074. "sourceHTTPFirewallRuleSetId": req.SourceHTTPFirewallRuleSetId,
  1075. "sourceURL": req.SourceURL,
  1076. "sourceUserAgent": req.SourceUserAgent,
  1077. "sourceCategory": req.SourceCategory,
  1078. }
  1079. apiUrl := s.Url + "IPItemService/createIPItem"
  1080. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  1081. if err != nil {
  1082. return err
  1083. }
  1084. var res v1.GeneralResponse[any]
  1085. if err := json.Unmarshal(resBody, &res); err != nil {
  1086. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  1087. }
  1088. if res.Code != 200 {
  1089. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  1090. }
  1091. return nil
  1092. }
  1093. // 修改IP
  1094. func (s *cdnService) EditIpItem(ctx context.Context, req v1.AddIpItem) error {
  1095. formData := map[string]interface{}{
  1096. "ipItemId": req.IpItemId,
  1097. "value": req.Value,
  1098. "reason" : req.Reason,
  1099. "type" : req.Type,
  1100. "eventLevel" : req.EventLevel,
  1101. }
  1102. apiUrl := s.Url + "IPItemService/updateIPItem"
  1103. resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
  1104. if err != nil {
  1105. return err
  1106. }
  1107. var res v1.GeneralResponse[any]
  1108. if err := json.Unmarshal(resBody, &res); err != nil {
  1109. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  1110. }
  1111. if res.Code != 200 {
  1112. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  1113. }
  1114. return nil
  1115. }