PageRenderTime 47ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/clc2vcf/pymodules/python2.7/lib/python/apache_libcloud-0.15.1-py2.7.egg/libcloud/dns/base.py

https://gitlab.com/pooja043/Globus_Docker_2
Python | 486 lines | 266 code | 41 blank | 179 comment | 15 complexity | 172146b6c5dab1dcc4ada6f224a5ebe3 MD5 | raw file
  1. # Licensed to the Apache Software Foundation (ASF) under one or more
  2. # contributor license agreements. See the NOTICE file distributed with
  3. # this work for additional information regarding copyright ownership.
  4. # The ASF licenses this file to You under the Apache License, Version 2.0
  5. # (the "License"); you may not use this file except in compliance with
  6. # the License. You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. from __future__ import with_statement
  16. import datetime
  17. from libcloud import __version__
  18. from libcloud.common.base import ConnectionUserAndKey, BaseDriver
  19. from libcloud.dns.types import RecordType
  20. __all__ = [
  21. 'Zone',
  22. 'Record',
  23. 'DNSDriver'
  24. ]
  25. class Zone(object):
  26. """
  27. DNS zone.
  28. """
  29. def __init__(self, id, domain, type, ttl, driver, extra=None):
  30. """
  31. :param id: Zone id.
  32. :type id: ``str``
  33. :param domain: The name of the domain.
  34. :type domain: ``str``
  35. :param type: Zone type (master, slave).
  36. :type type: ``str``
  37. :param ttl: Default TTL for records in this zone (in seconds).
  38. :type ttl: ``int``
  39. :param driver: DNSDriver instance.
  40. :type driver: :class:`DNSDriver`
  41. :param extra: (optional) Extra attributes (driver specific).
  42. :type extra: ``dict``
  43. """
  44. self.id = str(id) if id else None
  45. self.domain = domain
  46. self.type = type
  47. self.ttl = ttl or None
  48. self.driver = driver
  49. self.extra = extra or {}
  50. def list_records(self):
  51. return self.driver.list_records(zone=self)
  52. def create_record(self, name, type, data, extra=None):
  53. return self.driver.create_record(name=name, zone=self, type=type,
  54. data=data, extra=extra)
  55. def update(self, domain=None, type=None, ttl=None, extra=None):
  56. return self.driver.update_zone(zone=self, domain=domain, type=type,
  57. ttl=ttl, extra=extra)
  58. def delete(self):
  59. return self.driver.delete_zone(zone=self)
  60. def export_to_bind_format(self):
  61. return self.driver.export_zone_to_bind_format(zone=self)
  62. def export_to_bind_zone_file(self, file_path):
  63. self.driver.export_zone_to_bind_zone_file(zone=self,
  64. file_path=file_path)
  65. def __repr__(self):
  66. return ('<Zone: domain=%s, ttl=%s, provider=%s ...>' %
  67. (self.domain, self.ttl, self.driver.name))
  68. class Record(object):
  69. """
  70. Zone record / resource.
  71. """
  72. def __init__(self, id, name, type, data, zone, driver, extra=None):
  73. """
  74. :param id: Record id
  75. :type id: ``str``
  76. :param name: Hostname or FQDN.
  77. :type name: ``str``
  78. :param type: DNS record type (A, AAAA, ...).
  79. :type type: :class:`RecordType`
  80. :param data: Data for the record (depends on the record type).
  81. :type data: ``str``
  82. :param zone: Zone instance.
  83. :type zone: :class:`Zone`
  84. :param driver: DNSDriver instance.
  85. :type driver: :class:`DNSDriver`
  86. :param extra: (optional) Extra attributes (driver specific).
  87. :type extra: ``dict``
  88. """
  89. self.id = str(id) if id else None
  90. self.name = name
  91. self.type = type
  92. self.data = data
  93. self.zone = zone
  94. self.driver = driver
  95. self.extra = extra or {}
  96. def update(self, name=None, type=None, data=None, extra=None):
  97. return self.driver.update_record(record=self, name=name, type=type,
  98. data=data, extra=extra)
  99. def delete(self):
  100. return self.driver.delete_record(record=self)
  101. def _get_numeric_id(self):
  102. record_id = self.id
  103. if record_id.isdigit():
  104. record_id = int(record_id)
  105. return record_id
  106. def __repr__(self):
  107. return ('<Record: zone=%s, name=%s, type=%s, data=%s, provider=%s '
  108. '...>' %
  109. (self.zone.id, self.name, self.type, self.data,
  110. self.driver.name))
  111. class DNSDriver(BaseDriver):
  112. """
  113. A base DNSDriver class to derive from
  114. This class is always subclassed by a specific driver.
  115. """
  116. connectionCls = ConnectionUserAndKey
  117. name = None
  118. website = None
  119. def __init__(self, key, secret=None, secure=True, host=None, port=None,
  120. **kwargs):
  121. """
  122. :param key: API key or username to used (required)
  123. :type key: ``str``
  124. :param secret: Secret password to be used (required)
  125. :type secret: ``str``
  126. :param secure: Weither to use HTTPS or HTTP. Note: Some providers
  127. only support HTTPS, and it is on by default.
  128. :type secure: ``bool``
  129. :param host: Override hostname used for connections.
  130. :type host: ``str``
  131. :param port: Override port used for connections.
  132. :type port: ``int``
  133. :return: ``None``
  134. """
  135. super(DNSDriver, self).__init__(key=key, secret=secret, secure=secure,
  136. host=host, port=port, **kwargs)
  137. def list_record_types(self):
  138. """
  139. Return a list of RecordType objects supported by the provider.
  140. :return: ``list`` of :class:`RecordType`
  141. """
  142. return list(self.RECORD_TYPE_MAP.keys())
  143. def iterate_zones(self):
  144. """
  145. Return a generator to iterate over available zones.
  146. :rtype: ``generator`` of :class:`Zone`
  147. """
  148. raise NotImplementedError(
  149. 'iterate_zones not implemented for this driver')
  150. def list_zones(self):
  151. """
  152. Return a list of zones.
  153. :return: ``list`` of :class:`Zone`
  154. """
  155. return list(self.iterate_zones())
  156. def iterate_records(self, zone):
  157. """
  158. Return a generator to iterate over records for the provided zone.
  159. :param zone: Zone to list records for.
  160. :type zone: :class:`Zone`
  161. :rtype: ``generator`` of :class:`Record`
  162. """
  163. raise NotImplementedError(
  164. 'iterate_records not implemented for this driver')
  165. def list_records(self, zone):
  166. """
  167. Return a list of records for the provided zone.
  168. :param zone: Zone to list records for.
  169. :type zone: :class:`Zone`
  170. :return: ``list`` of :class:`Record`
  171. """
  172. return list(self.iterate_records(zone))
  173. def get_zone(self, zone_id):
  174. """
  175. Return a Zone instance.
  176. :param zone_id: ID of the required zone
  177. :type zone_id: ``str``
  178. :rtype: :class:`Zone`
  179. """
  180. raise NotImplementedError(
  181. 'get_zone not implemented for this driver')
  182. def get_record(self, zone_id, record_id):
  183. """
  184. Return a Record instance.
  185. :param zone_id: ID of the required zone
  186. :type zone_id: ``str``
  187. :param record_id: ID of the required record
  188. :type record_id: ``str``
  189. :rtype: :class:`Record`
  190. """
  191. raise NotImplementedError(
  192. 'get_record not implemented for this driver')
  193. def create_zone(self, domain, type='master', ttl=None, extra=None):
  194. """
  195. Create a new zone.
  196. :param domain: Zone domain name (e.g. example.com)
  197. :type domain: ``str``
  198. :param type: Zone type (master / slave).
  199. :type type: ``str``
  200. :param ttl: TTL for new records. (optional)
  201. :type ttl: ``int``
  202. :param extra: Extra attributes (driver specific). (optional)
  203. :type extra: ``dict``
  204. :rtype: :class:`Zone`
  205. """
  206. raise NotImplementedError(
  207. 'create_zone not implemented for this driver')
  208. def update_zone(self, zone, domain, type='master', ttl=None, extra=None):
  209. """
  210. Update en existing zone.
  211. :param zone: Zone to update.
  212. :type zone: :class:`Zone`
  213. :param domain: Zone domain name (e.g. example.com)
  214. :type domain: ``str``
  215. :param type: Zone type (master / slave).
  216. :type type: ``str``
  217. :param ttl: TTL for new records. (optional)
  218. :type ttl: ``int``
  219. :param extra: Extra attributes (driver specific). (optional)
  220. :type extra: ``dict``
  221. :rtype: :class:`Zone`
  222. """
  223. raise NotImplementedError(
  224. 'update_zone not implemented for this driver')
  225. def create_record(self, name, zone, type, data, extra=None):
  226. """
  227. Create a new record.
  228. :param name: Record name without the domain name (e.g. www).
  229. Note: If you want to create a record for a base domain
  230. name, you should specify empty string ('') for this
  231. argument.
  232. :type name: ``str``
  233. :param zone: Zone where the requested record is created.
  234. :type zone: :class:`Zone`
  235. :param type: DNS record type (A, AAAA, ...).
  236. :type type: :class:`RecordType`
  237. :param data: Data for the record (depends on the record type).
  238. :type data: ``str``
  239. :param extra: Extra attributes (driver specific). (optional)
  240. :type extra: ``dict``
  241. :rtype: :class:`Record`
  242. """
  243. raise NotImplementedError(
  244. 'create_record not implemented for this driver')
  245. def update_record(self, record, name, type, data, extra):
  246. """
  247. Update an existing record.
  248. :param record: Record to update.
  249. :type record: :class:`Record`
  250. :param name: Record name without the domain name (e.g. www).
  251. Note: If you want to create a record for a base domain
  252. name, you should specify empty string ('') for this
  253. argument.
  254. :type name: ``str``
  255. :param type: DNS record type (A, AAAA, ...).
  256. :type type: :class:`RecordType`
  257. :param data: Data for the record (depends on the record type).
  258. :type data: ``str``
  259. :param extra: (optional) Extra attributes (driver specific).
  260. :type extra: ``dict``
  261. :rtype: :class:`Record`
  262. """
  263. raise NotImplementedError(
  264. 'update_record not implemented for this driver')
  265. def delete_zone(self, zone):
  266. """
  267. Delete a zone.
  268. Note: This will delete all the records belonging to this zone.
  269. :param zone: Zone to delete.
  270. :type zone: :class:`Zone`
  271. :rtype: ``bool``
  272. """
  273. raise NotImplementedError(
  274. 'delete_zone not implemented for this driver')
  275. def delete_record(self, record):
  276. """
  277. Delete a record.
  278. :param record: Record to delete.
  279. :type record: :class:`Record`
  280. :rtype: ``bool``
  281. """
  282. raise NotImplementedError(
  283. 'delete_record not implemented for this driver')
  284. def export_zone_to_bind_format(self, zone):
  285. """
  286. Export Zone object to the BIND compatible format.
  287. :param zone: Zone to export.
  288. :type zone: :class:`Zone`
  289. :return: Zone data in BIND compatible format.
  290. :rtype: ``str``
  291. """
  292. if zone.type != 'master':
  293. raise ValueError('You can only generate BIND out for master zones')
  294. lines = []
  295. # For consistent output, records are sorted based on the id
  296. records = zone.list_records()
  297. records = sorted(records, key=Record._get_numeric_id)
  298. date = datetime.datetime.now().strftime('%Y-%m-%d %H:%m:%S')
  299. values = {'version': __version__, 'date': date}
  300. lines.append('; Generated by Libcloud v%(version)s on %(date)s' %
  301. values)
  302. lines.append('$ORIGIN %(domain)s.' % {'domain': zone.domain})
  303. lines.append('$TTL %(domain_ttl)s\n' % {'domain_ttl': zone.ttl})
  304. for record in records:
  305. line = self._get_bind_record_line(record=record)
  306. lines.append(line)
  307. output = '\n'.join(lines)
  308. return output
  309. def export_zone_to_bind_zone_file(self, zone, file_path):
  310. """
  311. Export Zone object to the BIND compatible format and write result to a
  312. file.
  313. :param zone: Zone to export.
  314. :type zone: :class:`Zone`
  315. :param file_path: File path where the output will be saved.
  316. :type file_path: ``str``
  317. """
  318. result = self.export_zone_to_bind_format(zone=zone)
  319. with open(file_path, 'w') as fp:
  320. fp.write(result)
  321. def _get_bind_record_line(self, record):
  322. """
  323. Generate BIND record line for the provided record.
  324. :param record: Record to generate the line for.
  325. :type record: :class:`Record`
  326. :return: Bind compatible record line.
  327. :rtype: ``str``
  328. """
  329. parts = []
  330. if record.name:
  331. name = '%(name)s.%(domain)s' % {'name': record.name,
  332. 'domain': record.zone.domain}
  333. else:
  334. name = record.zone.domain
  335. name += '.'
  336. ttl = record.extra['ttl'] if 'ttl' in record.extra else record.zone.ttl
  337. ttl = str(ttl)
  338. data = record.data
  339. if record.type in [RecordType.CNAME, RecordType.DNAME, RecordType.MX,
  340. RecordType.PTR, RecordType.SRV]:
  341. # Make sure trailing dot is present
  342. if data[len(data) - 1] != '.':
  343. data += '.'
  344. if record.type in [RecordType.TXT, RecordType.SPF] and ' ' in data:
  345. # Escape the quotes
  346. data = data.replace('"', '\\"')
  347. # Quote the string
  348. data = '"%s"' % (data)
  349. if record.type in [RecordType.MX, RecordType.SRV]:
  350. priority = str(record.extra['priority'])
  351. parts = [name, ttl, 'IN', record.type, priority, data]
  352. else:
  353. parts = [name, ttl, 'IN', record.type, data]
  354. line = '\t'.join(parts)
  355. return line
  356. def _string_to_record_type(self, string):
  357. """
  358. Return a string representation of a DNS record type to a
  359. libcloud RecordType ENUM.
  360. :rtype: ``str``
  361. """
  362. string = string.upper()
  363. record_type = getattr(RecordType, string)
  364. return record_type