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