dnscom.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. # coding=utf-8
  2. """
  3. DNSCOM/51dns API 接口解析操作库
  4. www.51dns.com (原dns.com)
  5. @author: Bigjin<[email protected]>, NewFuture
  6. """
  7. from ._base import BaseProvider, TYPE_FORM
  8. from hashlib import md5
  9. from time import time
  10. class DnscomProvider(BaseProvider):
  11. """
  12. DNSCOM/51dns API Provider
  13. https://www.51dns.com/document/api/index.html
  14. """
  15. API = "https://www.51dns.com"
  16. content_type = TYPE_FORM
  17. def _validate(self):
  18. self.logger.warning(
  19. "DNS.COM 缺少充分的真实环境测试,请及时在 GitHub Issues 中反馈: %s",
  20. "https://github.com/NewFuture/DDNS/issues",
  21. )
  22. super(DnscomProvider, self)._validate()
  23. def _signature(self, params):
  24. """https://www.51dns.com/document/api/70/72.html"""
  25. params = {k: v for k, v in params.items() if v is not None}
  26. params.update(
  27. {
  28. "apiKey": self.auth_id,
  29. "timestamp": time(), # 时间戳
  30. }
  31. )
  32. query = self._encode(sorted(params.items()))
  33. sign = md5((query + self.auth_token).encode("utf-8")).hexdigest()
  34. params["hash"] = sign
  35. return params
  36. def _request(self, action, **params):
  37. params = self._signature(params)
  38. data = self._http("POST", "/api/{}/".format(action), body=params)
  39. if data is None or not isinstance(data, dict):
  40. raise Exception("response data is none")
  41. if data.get("code", 0) != 0:
  42. raise Exception("api error: " + str(data.get("message")))
  43. return data.get("data")
  44. def _query_zone_id(self, domain):
  45. """https://www.51dns.com/document/api/74/31.html"""
  46. res = self._request("domain/getsingle", domainID=domain)
  47. self.logger.debug("Queried domain: %s", res)
  48. if res:
  49. return res.get("domainID")
  50. return None
  51. def _query_record(self, zone_id, subdomain, main_domain, record_type, line, extra):
  52. """https://www.51dns.com/document/api/4/47.html"""
  53. records = self._request("record/list", domainID=zone_id, host=subdomain, pageSize=500)
  54. records = records.get("data", []) if records else []
  55. for record in records:
  56. if (
  57. record.get("record") == subdomain
  58. and record.get("type") == record_type
  59. and (line is None or record.get("viewID") == line)
  60. ):
  61. return record
  62. return None
  63. def _create_record(self, zone_id, subdomain, main_domain, value, record_type, ttl, line, extra):
  64. """https://www.51dns.com/document/api/4/12.html"""
  65. extra["remark"] = extra.get("remark", self.remark)
  66. res = self._request(
  67. "record/create",
  68. domainID=zone_id,
  69. value=value,
  70. host=subdomain,
  71. type=record_type,
  72. TTL=ttl,
  73. viewID=line,
  74. **extra
  75. )
  76. if res and res.get("recordID"):
  77. self.logger.info("Record created: %s", res)
  78. return True
  79. self.logger.error("Failed to create record: %s", res)
  80. return False
  81. def _update_record(self, zone_id, old_record, value, record_type, ttl, line, extra):
  82. """https://www.51dns.com/document/api/4/45.html"""
  83. extra["remark"] = extra.get("remark", self.remark)
  84. res = self._request(
  85. "record/modify", domainID=zone_id, recordID=old_record.get("recordID"), newvalue=value, newTTL=ttl
  86. )
  87. if res:
  88. self.logger.info("Record updated: %s", res)
  89. return True
  90. self.logger.error("Failed to update record: %s", res)
  91. return False