dns_requestacl_python.cc 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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. // Enable this if you use s# variants with PyArg_ParseTuple(), see
  15. // http://docs.python.org/py3k/c-api/arg.html#strings-and-buffers
  16. //#define PY_SSIZE_T_CLEAN
  17. // Python.h needs to be placed at the head of the program file, see:
  18. // http://docs.python.org/py3k/extending/extending.html#a-simple-example
  19. #include <Python.h>
  20. #include <string>
  21. #include <stdexcept>
  22. #include <util/python/pycppwrapper_util.h>
  23. #include <acl/acl.h>
  24. #include <acl/dns.h>
  25. #include "dns.h"
  26. #include "dns_requestacl_python.h"
  27. #include "dns_requestcontext_python.h"
  28. using namespace std;
  29. using namespace isc::util::python;
  30. using namespace isc::acl;
  31. using namespace isc::acl::dns;
  32. using namespace isc::acl::dns::python;
  33. //
  34. // Definition of the classes
  35. //
  36. // For each class, we need a struct, a helper functions (init, destroy,
  37. // and static wrappers around the methods we export), a list of methods,
  38. // and a type description
  39. //
  40. // RequestACL
  41. //
  42. // Trivial constructor.
  43. s_RequestACL::s_RequestACL() {}
  44. // Import pydoc text
  45. #include "dns_requestacl_inc.cc"
  46. namespace {
  47. int
  48. RequestACL_init(PyObject*, PyObject*, PyObject*) {
  49. PyErr_SetString(getACLException("Error"),
  50. "RequestACL cannot be directly constructed");
  51. return (-1);
  52. }
  53. void
  54. RequestACL_destroy(PyObject* po_self) {
  55. s_RequestACL* const self = static_cast<s_RequestACL*>(po_self);
  56. self->cppobj.reset();
  57. Py_TYPE(self)->tp_free(self);
  58. }
  59. PyObject*
  60. RequestACL_execute(PyObject* po_self, PyObject* args) {
  61. s_RequestACL* const self = static_cast<s_RequestACL*>(po_self);
  62. try {
  63. const s_RequestContext* po_context;
  64. if (PyArg_ParseTuple(args, "O!", &requestcontext_type, &po_context)) {
  65. const BasicAction action =
  66. self->cppobj->execute(*po_context->cppobj);
  67. return (Py_BuildValue("I", action));
  68. }
  69. } catch (const exception& ex) {
  70. const string ex_what = "Failed to execute ACL: " + string(ex.what());
  71. PyErr_SetString(getACLException("Error"), ex_what.c_str());
  72. } catch (...) {
  73. PyErr_SetString(PyExc_RuntimeError,
  74. "Unexpected exception in executing ACL");
  75. }
  76. return (NULL);
  77. }
  78. // This list contains the actual set of functions we have in
  79. // python. Each entry has
  80. // 1. Python method name
  81. // 2. Our static function here
  82. // 3. Argument type
  83. // 4. Documentation
  84. PyMethodDef RequestACL_methods[] = {
  85. { "execute", RequestACL_execute, METH_VARARGS, RequestACL_execute_doc },
  86. { NULL, NULL, 0, NULL }
  87. };
  88. } // end of unnamed namespace
  89. namespace isc {
  90. namespace acl {
  91. namespace dns {
  92. namespace python {
  93. // This defines the complete type for reflection in python and
  94. // parsing of PyObject* to s_RequestACL
  95. // Most of the functions are not actually implemented and NULL here.
  96. PyTypeObject requestacl_type = {
  97. PyVarObject_HEAD_INIT(NULL, 0)
  98. "isc.acl._dns.RequestACL",
  99. sizeof(s_RequestACL), // tp_basicsize
  100. 0, // tp_itemsize
  101. RequestACL_destroy, // tp_dealloc
  102. NULL, // tp_print
  103. NULL, // tp_getattr
  104. NULL, // tp_setattr
  105. NULL, // tp_reserved
  106. NULL, // tp_repr
  107. NULL, // tp_as_number
  108. NULL, // tp_as_sequence
  109. NULL, // tp_as_mapping
  110. NULL, // tp_hash
  111. NULL, // tp_call
  112. NULL, // tp_str
  113. NULL, // tp_getattro
  114. NULL, // tp_setattro
  115. NULL, // tp_as_buffer
  116. Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, // tp_flags
  117. RequestACL_doc,
  118. NULL, // tp_traverse
  119. NULL, // tp_clear
  120. NULL, // tp_richcompare
  121. 0, // tp_weaklistoffset
  122. NULL, // tp_iter
  123. NULL, // tp_iternext
  124. RequestACL_methods, // tp_methods
  125. NULL, // tp_members
  126. NULL, // tp_getset
  127. NULL, // tp_base
  128. NULL, // tp_dict
  129. NULL, // tp_descr_get
  130. NULL, // tp_descr_set
  131. 0, // tp_dictoffset
  132. RequestACL_init, // tp_init
  133. NULL, // tp_alloc
  134. PyType_GenericNew, // tp_new
  135. NULL, // tp_free
  136. NULL, // tp_is_gc
  137. NULL, // tp_bases
  138. NULL, // tp_mro
  139. NULL, // tp_cache
  140. NULL, // tp_subclasses
  141. NULL, // tp_weaklist
  142. NULL, // tp_del
  143. 0 // tp_version_tag
  144. };
  145. bool
  146. initModulePart_RequestACL(PyObject* mod) {
  147. // We initialize the static description object with PyType_Ready(),
  148. // then add it to the module. This is not just a check! (leaving
  149. // this out results in segmentation faults)
  150. if (PyType_Ready(&requestacl_type) < 0) {
  151. return (false);
  152. }
  153. void* p = &requestacl_type;
  154. if (PyModule_AddObject(mod, "RequestACL", static_cast<PyObject*>(p)) < 0) {
  155. return (false);
  156. }
  157. Py_INCREF(&requestacl_type);
  158. return (true);
  159. }
  160. } // namespace python
  161. } // namespace dns
  162. } // namespace acl
  163. } // namespace isc