datasrc.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  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 <log/message_initializer.h>
  23. #include "datasrc.h"
  24. #include "client_python.h"
  25. #include "finder_python.h"
  26. #include "iterator_python.h"
  27. #include "updater_python.h"
  28. #include "journal_reader_python.h"
  29. #include "configurableclientlist_python.h"
  30. #include "zone_loader_python.h"
  31. #include "zonewriter_python.h"
  32. #include <util/python/pycppwrapper_util.h>
  33. #include <dns/python/pydnspp_common.h>
  34. #include <stdexcept>
  35. #include <string>
  36. using namespace isc::datasrc;
  37. using namespace isc::datasrc::python;
  38. using namespace isc::datasrc::memory::python;
  39. using namespace isc::util::python;
  40. using namespace isc::dns::python;
  41. namespace isc {
  42. namespace datasrc {
  43. namespace python {
  44. PyObject*
  45. getDataSourceException(const char* ex_name) {
  46. PyObject* ex_obj = NULL;
  47. PyObject* datasrc_module = PyImport_AddModule("isc.datasrc");
  48. if (datasrc_module != NULL) {
  49. PyObject* datasrc_dict = PyModule_GetDict(datasrc_module);
  50. if (datasrc_dict != NULL) {
  51. ex_obj = PyDict_GetItemString(datasrc_dict, ex_name);
  52. }
  53. }
  54. if (ex_obj == NULL) {
  55. ex_obj = PyExc_RuntimeError;
  56. }
  57. return (ex_obj);
  58. }
  59. } // end namespace python
  60. } // end namespace datasrc
  61. } // end namespace isc
  62. namespace {
  63. bool
  64. initModulePart_DataSourceClient(PyObject* mod) {
  65. // We initialize the static description object with PyType_Ready(),
  66. // then add it to the module. This is not just a check! (leaving
  67. // this out results in segmentation faults)
  68. if (PyType_Ready(&datasourceclient_type) < 0) {
  69. return (false);
  70. }
  71. void* dscp = &datasourceclient_type;
  72. if (PyModule_AddObject(mod, "DataSourceClient", static_cast<PyObject*>(dscp)) < 0) {
  73. return (false);
  74. }
  75. Py_INCREF(&datasourceclient_type);
  76. try {
  77. installClassVariable(datasourceclient_type, "SUCCESS",
  78. Py_BuildValue("I", result::SUCCESS));
  79. installClassVariable(datasourceclient_type, "EXIST",
  80. Py_BuildValue("I", result::EXIST));
  81. installClassVariable(datasourceclient_type, "NOTFOUND",
  82. Py_BuildValue("I", result::NOTFOUND));
  83. installClassVariable(datasourceclient_type, "PARTIALMATCH",
  84. Py_BuildValue("I", result::PARTIALMATCH));
  85. } catch (const std::exception& ex) {
  86. const std::string ex_what =
  87. "Unexpected failure in DataSourceClient initialization: " +
  88. std::string(ex.what());
  89. PyErr_SetString(po_IscException, ex_what.c_str());
  90. return (false);
  91. } catch (...) {
  92. PyErr_SetString(PyExc_SystemError,
  93. "Unexpected failure in DataSourceClient initialization");
  94. return (false);
  95. }
  96. return (true);
  97. }
  98. bool
  99. initModulePart_ZoneFinder(PyObject* mod) {
  100. // We initialize the static description object with PyType_Ready(),
  101. // then add it to the module. This is not just a check! (leaving
  102. // this out results in segmentation faults)
  103. if (PyType_Ready(&zonefinder_type) < 0) {
  104. return (false);
  105. }
  106. void* zip = &zonefinder_type;
  107. if (PyModule_AddObject(mod, "ZoneFinder", static_cast<PyObject*>(zip)) < 0) {
  108. return (false);
  109. }
  110. Py_INCREF(&zonefinder_type);
  111. try {
  112. installClassVariable(zonefinder_type, "SUCCESS",
  113. Py_BuildValue("I", ZoneFinder::SUCCESS));
  114. installClassVariable(zonefinder_type, "DELEGATION",
  115. Py_BuildValue("I", ZoneFinder::DELEGATION));
  116. installClassVariable(zonefinder_type, "NXDOMAIN",
  117. Py_BuildValue("I", ZoneFinder::NXDOMAIN));
  118. installClassVariable(zonefinder_type, "NXRRSET",
  119. Py_BuildValue("I", ZoneFinder::NXRRSET));
  120. installClassVariable(zonefinder_type, "CNAME",
  121. Py_BuildValue("I", ZoneFinder::CNAME));
  122. installClassVariable(zonefinder_type, "DNAME",
  123. Py_BuildValue("I", ZoneFinder::DNAME));
  124. installClassVariable(zonefinder_type, "FIND_DEFAULT",
  125. Py_BuildValue("I", ZoneFinder::FIND_DEFAULT));
  126. installClassVariable(zonefinder_type, "FIND_GLUE_OK",
  127. Py_BuildValue("I", ZoneFinder::FIND_GLUE_OK));
  128. installClassVariable(zonefinder_type, "FIND_DNSSEC",
  129. Py_BuildValue("I", ZoneFinder::FIND_DNSSEC));
  130. installClassVariable(zonefinder_type, "NO_WILDCARD",
  131. Py_BuildValue("I", ZoneFinder::NO_WILDCARD));
  132. installClassVariable(zonefinder_type, "RESULT_WILDCARD",
  133. Py_BuildValue("I", ZoneFinder::RESULT_WILDCARD));
  134. installClassVariable(zonefinder_type, "RESULT_NSEC_SIGNED",
  135. Py_BuildValue("I",
  136. ZoneFinder::RESULT_NSEC_SIGNED));
  137. installClassVariable(zonefinder_type, "RESULT_NSEC3_SIGNED",
  138. Py_BuildValue("I",
  139. ZoneFinder::RESULT_NSEC3_SIGNED));
  140. } catch (const std::exception& ex) {
  141. const std::string ex_what =
  142. "Unexpected failure in ZoneFinder initialization: " +
  143. std::string(ex.what());
  144. PyErr_SetString(po_IscException, ex_what.c_str());
  145. return (false);
  146. } catch (...) {
  147. PyErr_SetString(PyExc_SystemError,
  148. "Unexpected failure in ZoneFinder initialization");
  149. return (false);
  150. }
  151. return (true);
  152. }
  153. bool
  154. initModulePart_ZoneIterator(PyObject* mod) {
  155. // We initialize the static description object with PyType_Ready(),
  156. // then add it to the module. This is not just a check! (leaving
  157. // this out results in segmentation faults)
  158. if (PyType_Ready(&zoneiterator_type) < 0) {
  159. return (false);
  160. }
  161. void* zip = &zoneiterator_type;
  162. if (PyModule_AddObject(mod, "ZoneIterator", static_cast<PyObject*>(zip)) < 0) {
  163. return (false);
  164. }
  165. Py_INCREF(&zoneiterator_type);
  166. return (true);
  167. }
  168. bool
  169. initModulePart_ZoneLoader(PyObject* mod) {
  170. // We initialize the static description object with PyType_Ready(),
  171. // then add it to the module. This is not just a check! (leaving
  172. // this out results in segmentation faults)
  173. if (PyType_Ready(&zone_loader_type) < 0) {
  174. return (false);
  175. }
  176. void* p = &zone_loader_type;
  177. if (PyModule_AddObject(mod, "ZoneLoader", static_cast<PyObject*>(p)) < 0) {
  178. return (false);
  179. }
  180. Py_INCREF(&zone_loader_type);
  181. try {
  182. installClassVariable(zone_loader_type, "PROGRESS_UNKNOWN",
  183. Py_BuildValue("d", ZoneLoader::PROGRESS_UNKNOWN));
  184. } catch (const std::exception& ex) {
  185. const std::string ex_what =
  186. "Unexpected failure in ZoneLoader initialization: " +
  187. std::string(ex.what());
  188. PyErr_SetString(po_IscException, ex_what.c_str());
  189. return (false);
  190. } catch (...) {
  191. PyErr_SetString(PyExc_SystemError,
  192. "Unexpected failure in ZoneLoader initialization");
  193. return (false);
  194. }
  195. return (true);
  196. }
  197. bool
  198. initModulePart_ZoneJournalReader(PyObject* mod) {
  199. if (PyType_Ready(&journal_reader_type) < 0) {
  200. return (false);
  201. }
  202. void* p = &journal_reader_type;
  203. if (PyModule_AddObject(mod, "ZoneJournalReader",
  204. static_cast<PyObject*>(p)) < 0) {
  205. return (false);
  206. }
  207. Py_INCREF(&journal_reader_type);
  208. try {
  209. installClassVariable(journal_reader_type, "SUCCESS",
  210. Py_BuildValue("I", ZoneJournalReader::SUCCESS));
  211. installClassVariable(journal_reader_type, "NO_SUCH_ZONE",
  212. Py_BuildValue("I",
  213. ZoneJournalReader::NO_SUCH_ZONE));
  214. installClassVariable(journal_reader_type, "NO_SUCH_VERSION",
  215. Py_BuildValue("I",
  216. ZoneJournalReader::NO_SUCH_VERSION));
  217. } catch (const std::exception& ex) {
  218. const std::string ex_what =
  219. "Unexpected failure in ZoneJournalReader initialization: " +
  220. std::string(ex.what());
  221. PyErr_SetString(po_IscException, ex_what.c_str());
  222. return (false);
  223. } catch (...) {
  224. PyErr_SetString(PyExc_SystemError,
  225. "Unexpected failure in ZoneJournalReader initialization");
  226. return (false);
  227. }
  228. return (true);
  229. }
  230. PyObject* po_DataSourceError;
  231. PyObject* po_MasterFileError;
  232. PyObject* po_NotImplemented;
  233. PyObject* po_OutOfZone;
  234. PyModuleDef iscDataSrc = {
  235. { PyObject_HEAD_INIT(NULL) NULL, 0, NULL},
  236. "datasrc",
  237. "Python bindings for the classes in the isc::datasrc namespace.\n\n"
  238. "These bindings are close match to the C++ API, but they are not complete "
  239. "(some parts are not needed) and some are done in more python-like ways.",
  240. -1,
  241. NULL,
  242. NULL,
  243. NULL,
  244. NULL,
  245. NULL
  246. };
  247. } // end anonymous namespace
  248. PyMODINIT_FUNC
  249. PyInit_datasrc(void) {
  250. isc::log::MessageInitializer::loadDictionary();
  251. PyObject* mod = PyModule_Create(&iscDataSrc);
  252. if (mod == NULL) {
  253. return (NULL);
  254. }
  255. try {
  256. po_DataSourceError = PyErr_NewException("isc.datasrc.Error", NULL,
  257. NULL);
  258. PyObjectContainer(po_DataSourceError).installToModule(mod, "Error");
  259. po_MasterFileError = PyErr_NewException("isc.datasrc.MasterFileError",
  260. po_DataSourceError, NULL);
  261. PyObjectContainer(po_MasterFileError).
  262. installToModule(mod, "MasterFileError");
  263. po_OutOfZone = PyErr_NewException("isc.datasrc.OutOfZone", NULL, NULL);
  264. PyObjectContainer(po_OutOfZone).installToModule(mod, "OutOfZone");
  265. po_NotImplemented = PyErr_NewException("isc.datasrc.NotImplemented",
  266. NULL, NULL);
  267. PyObjectContainer(po_NotImplemented).installToModule(mod,
  268. "NotImplemented");
  269. } catch (...) {
  270. Py_DECREF(mod);
  271. return (NULL);
  272. }
  273. if (!initModulePart_DataSourceClient(mod)) {
  274. Py_DECREF(mod);
  275. return (NULL);
  276. }
  277. if (!initModulePart_ZoneFinder(mod)) {
  278. Py_DECREF(mod);
  279. return (NULL);
  280. }
  281. if (!initModulePart_ZoneIterator(mod)) {
  282. Py_DECREF(mod);
  283. return (NULL);
  284. }
  285. if (!initModulePart_ZoneUpdater(mod)) {
  286. Py_DECREF(mod);
  287. return (NULL);
  288. }
  289. if (!initModulePart_ZoneJournalReader(mod)) {
  290. Py_DECREF(mod);
  291. return (NULL);
  292. }
  293. if (!initModulePart_ConfigurableClientList(mod)) {
  294. Py_DECREF(mod);
  295. return (NULL);
  296. }
  297. if (!initModulePart_ZoneLoader(mod)) {
  298. Py_DECREF(mod);
  299. return (NULL);
  300. }
  301. if (!initModulePart_ZoneWriter(mod)) {
  302. Py_DECREF(mod);
  303. return (NULL);
  304. }
  305. return (mod);
  306. }