datasrc.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #define PY_SSIZE_T_CLEAN
  15. #include <Python.h>
  16. #include <structmember.h>
  17. #include <config.h>
  18. #include <datasrc/client.h>
  19. #include <datasrc/database.h>
  20. #include <datasrc/sqlite3_accessor.h>
  21. #include <datasrc/zone_loader.h>
  22. #include "datasrc.h"
  23. #include "client_python.h"
  24. #include "finder_python.h"
  25. #include "iterator_python.h"
  26. #include "updater_python.h"
  27. #include "journal_reader_python.h"
  28. #include "configurableclientlist_python.h"
  29. #include "zone_loader_python.h"
  30. #include <util/python/pycppwrapper_util.h>
  31. #include <dns/python/pydnspp_common.h>
  32. #include <stdexcept>
  33. #include <string>
  34. using namespace isc::datasrc;
  35. using namespace isc::datasrc::python;
  36. using namespace isc::util::python;
  37. using namespace isc::dns::python;
  38. namespace isc {
  39. namespace datasrc {
  40. namespace python {
  41. PyObject*
  42. getDataSourceException(const char* ex_name) {
  43. PyObject* ex_obj = NULL;
  44. PyObject* datasrc_module = PyImport_AddModule("isc.datasrc");
  45. if (datasrc_module != NULL) {
  46. PyObject* datasrc_dict = PyModule_GetDict(datasrc_module);
  47. if (datasrc_dict != NULL) {
  48. ex_obj = PyDict_GetItemString(datasrc_dict, ex_name);
  49. }
  50. }
  51. if (ex_obj == NULL) {
  52. ex_obj = PyExc_RuntimeError;
  53. }
  54. return (ex_obj);
  55. }
  56. } // end namespace python
  57. } // end namespace datasrc
  58. } // end namespace isc
  59. namespace {
  60. bool
  61. initModulePart_DataSourceClient(PyObject* mod) {
  62. // We initialize the static description object with PyType_Ready(),
  63. // then add it to the module. This is not just a check! (leaving
  64. // this out results in segmentation faults)
  65. if (PyType_Ready(&datasourceclient_type) < 0) {
  66. return (false);
  67. }
  68. void* dscp = &datasourceclient_type;
  69. if (PyModule_AddObject(mod, "DataSourceClient", static_cast<PyObject*>(dscp)) < 0) {
  70. return (false);
  71. }
  72. Py_INCREF(&datasourceclient_type);
  73. try {
  74. installClassVariable(datasourceclient_type, "SUCCESS",
  75. Py_BuildValue("I", result::SUCCESS));
  76. installClassVariable(datasourceclient_type, "EXIST",
  77. Py_BuildValue("I", result::EXIST));
  78. installClassVariable(datasourceclient_type, "NOTFOUND",
  79. Py_BuildValue("I", result::NOTFOUND));
  80. installClassVariable(datasourceclient_type, "PARTIALMATCH",
  81. Py_BuildValue("I", result::PARTIALMATCH));
  82. } catch (const std::exception& ex) {
  83. const std::string ex_what =
  84. "Unexpected failure in DataSourceClient initialization: " +
  85. std::string(ex.what());
  86. PyErr_SetString(po_IscException, ex_what.c_str());
  87. return (false);
  88. } catch (...) {
  89. PyErr_SetString(PyExc_SystemError,
  90. "Unexpected failure in DataSourceClient initialization");
  91. return (false);
  92. }
  93. return (true);
  94. }
  95. bool
  96. initModulePart_ZoneFinder(PyObject* mod) {
  97. // We initialize the static description object with PyType_Ready(),
  98. // then add it to the module. This is not just a check! (leaving
  99. // this out results in segmentation faults)
  100. if (PyType_Ready(&zonefinder_type) < 0) {
  101. return (false);
  102. }
  103. void* zip = &zonefinder_type;
  104. if (PyModule_AddObject(mod, "ZoneFinder", static_cast<PyObject*>(zip)) < 0) {
  105. return (false);
  106. }
  107. Py_INCREF(&zonefinder_type);
  108. try {
  109. installClassVariable(zonefinder_type, "SUCCESS",
  110. Py_BuildValue("I", ZoneFinder::SUCCESS));
  111. installClassVariable(zonefinder_type, "DELEGATION",
  112. Py_BuildValue("I", ZoneFinder::DELEGATION));
  113. installClassVariable(zonefinder_type, "NXDOMAIN",
  114. Py_BuildValue("I", ZoneFinder::NXDOMAIN));
  115. installClassVariable(zonefinder_type, "NXRRSET",
  116. Py_BuildValue("I", ZoneFinder::NXRRSET));
  117. installClassVariable(zonefinder_type, "CNAME",
  118. Py_BuildValue("I", ZoneFinder::CNAME));
  119. installClassVariable(zonefinder_type, "DNAME",
  120. Py_BuildValue("I", ZoneFinder::DNAME));
  121. installClassVariable(zonefinder_type, "FIND_DEFAULT",
  122. Py_BuildValue("I", ZoneFinder::FIND_DEFAULT));
  123. installClassVariable(zonefinder_type, "FIND_GLUE_OK",
  124. Py_BuildValue("I", ZoneFinder::FIND_GLUE_OK));
  125. installClassVariable(zonefinder_type, "FIND_DNSSEC",
  126. Py_BuildValue("I", ZoneFinder::FIND_DNSSEC));
  127. installClassVariable(zonefinder_type, "NO_WILDCARD",
  128. Py_BuildValue("I", ZoneFinder::NO_WILDCARD));
  129. installClassVariable(zonefinder_type, "RESULT_WILDCARD",
  130. Py_BuildValue("I", ZoneFinder::RESULT_WILDCARD));
  131. installClassVariable(zonefinder_type, "RESULT_NSEC_SIGNED",
  132. Py_BuildValue("I",
  133. ZoneFinder::RESULT_NSEC_SIGNED));
  134. installClassVariable(zonefinder_type, "RESULT_NSEC3_SIGNED",
  135. Py_BuildValue("I",
  136. ZoneFinder::RESULT_NSEC3_SIGNED));
  137. } catch (const std::exception& ex) {
  138. const std::string ex_what =
  139. "Unexpected failure in ZoneFinder initialization: " +
  140. std::string(ex.what());
  141. PyErr_SetString(po_IscException, ex_what.c_str());
  142. return (false);
  143. } catch (...) {
  144. PyErr_SetString(PyExc_SystemError,
  145. "Unexpected failure in ZoneFinder initialization");
  146. return (false);
  147. }
  148. return (true);
  149. }
  150. bool
  151. initModulePart_ZoneIterator(PyObject* mod) {
  152. // We initialize the static description object with PyType_Ready(),
  153. // then add it to the module. This is not just a check! (leaving
  154. // this out results in segmentation faults)
  155. if (PyType_Ready(&zoneiterator_type) < 0) {
  156. return (false);
  157. }
  158. void* zip = &zoneiterator_type;
  159. if (PyModule_AddObject(mod, "ZoneIterator", static_cast<PyObject*>(zip)) < 0) {
  160. return (false);
  161. }
  162. Py_INCREF(&zoneiterator_type);
  163. return (true);
  164. }
  165. bool
  166. initModulePart_ZoneLoader(PyObject* mod) {
  167. // We initialize the static description object with PyType_Ready(),
  168. // then add it to the module. This is not just a check! (leaving
  169. // this out results in segmentation faults)
  170. if (PyType_Ready(&zone_loader_type) < 0) {
  171. return (false);
  172. }
  173. void* p = &zone_loader_type;
  174. if (PyModule_AddObject(mod, "ZoneLoader", static_cast<PyObject*>(p)) < 0) {
  175. return (false);
  176. }
  177. Py_INCREF(&zone_loader_type);
  178. try {
  179. installClassVariable(zone_loader_type, "PROGRESS_UNKNOWN",
  180. Py_BuildValue("d", ZoneLoader::PROGRESS_UNKNOWN));
  181. } catch (const std::exception& ex) {
  182. const std::string ex_what =
  183. "Unexpected failure in ZoneLoader initialization: " +
  184. std::string(ex.what());
  185. PyErr_SetString(po_IscException, ex_what.c_str());
  186. return (false);
  187. } catch (...) {
  188. PyErr_SetString(PyExc_SystemError,
  189. "Unexpected failure in ZoneLoader initialization");
  190. return (false);
  191. }
  192. return (true);
  193. }
  194. bool
  195. initModulePart_ZoneJournalReader(PyObject* mod) {
  196. if (PyType_Ready(&journal_reader_type) < 0) {
  197. return (false);
  198. }
  199. void* p = &journal_reader_type;
  200. if (PyModule_AddObject(mod, "ZoneJournalReader",
  201. static_cast<PyObject*>(p)) < 0) {
  202. return (false);
  203. }
  204. Py_INCREF(&journal_reader_type);
  205. try {
  206. installClassVariable(journal_reader_type, "SUCCESS",
  207. Py_BuildValue("I", ZoneJournalReader::SUCCESS));
  208. installClassVariable(journal_reader_type, "NO_SUCH_ZONE",
  209. Py_BuildValue("I",
  210. ZoneJournalReader::NO_SUCH_ZONE));
  211. installClassVariable(journal_reader_type, "NO_SUCH_VERSION",
  212. Py_BuildValue("I",
  213. ZoneJournalReader::NO_SUCH_VERSION));
  214. } catch (const std::exception& ex) {
  215. const std::string ex_what =
  216. "Unexpected failure in ZoneJournalReader initialization: " +
  217. std::string(ex.what());
  218. PyErr_SetString(po_IscException, ex_what.c_str());
  219. return (false);
  220. } catch (...) {
  221. PyErr_SetString(PyExc_SystemError,
  222. "Unexpected failure in ZoneJournalReader initialization");
  223. return (false);
  224. }
  225. return (true);
  226. }
  227. PyObject* po_DataSourceError;
  228. PyObject* po_MasterFileError;
  229. PyObject* po_NotImplemented;
  230. PyObject* po_OutOfZone;
  231. PyModuleDef iscDataSrc = {
  232. { PyObject_HEAD_INIT(NULL) NULL, 0, NULL},
  233. "datasrc",
  234. "Python bindings for the classes in the isc::datasrc namespace.\n\n"
  235. "These bindings are close match to the C++ API, but they are not complete "
  236. "(some parts are not needed) and some are done in more python-like ways.",
  237. -1,
  238. NULL,
  239. NULL,
  240. NULL,
  241. NULL,
  242. NULL
  243. };
  244. } // end anonymous namespace
  245. PyMODINIT_FUNC
  246. PyInit_datasrc(void) {
  247. PyObject* mod = PyModule_Create(&iscDataSrc);
  248. if (mod == NULL) {
  249. return (NULL);
  250. }
  251. try {
  252. po_DataSourceError = PyErr_NewException("isc.datasrc.Error", NULL,
  253. NULL);
  254. PyObjectContainer(po_DataSourceError).installToModule(mod, "Error");
  255. po_MasterFileError = PyErr_NewException("isc.datasrc.MasterFileError",
  256. po_DataSourceError, NULL);
  257. PyObjectContainer(po_MasterFileError).
  258. installToModule(mod, "MasterFileError");
  259. po_OutOfZone = PyErr_NewException("isc.datasrc.OutOfZone", NULL, NULL);
  260. PyObjectContainer(po_OutOfZone).installToModule(mod, "OutOfZone");
  261. po_NotImplemented = PyErr_NewException("isc.datasrc.NotImplemented",
  262. NULL, NULL);
  263. PyObjectContainer(po_NotImplemented).installToModule(mod,
  264. "NotImplemented");
  265. } catch (...) {
  266. Py_DECREF(mod);
  267. return (NULL);
  268. }
  269. if (!initModulePart_DataSourceClient(mod)) {
  270. Py_DECREF(mod);
  271. return (NULL);
  272. }
  273. if (!initModulePart_ZoneFinder(mod)) {
  274. Py_DECREF(mod);
  275. return (NULL);
  276. }
  277. if (!initModulePart_ZoneIterator(mod)) {
  278. Py_DECREF(mod);
  279. return (NULL);
  280. }
  281. if (!initModulePart_ZoneUpdater(mod)) {
  282. Py_DECREF(mod);
  283. return (NULL);
  284. }
  285. if (!initModulePart_ZoneJournalReader(mod)) {
  286. Py_DECREF(mod);
  287. return (NULL);
  288. }
  289. if (!initModulePart_ConfigurableClientList(mod)) {
  290. Py_DECREF(mod);
  291. return (NULL);
  292. }
  293. if (!initModulePart_ZoneLoader(mod)) {
  294. Py_DECREF(mod);
  295. return (NULL);
  296. }
  297. return (mod);
  298. }