source: trunk/debathena/debathena/python-moira/_moira.pyx @ 24605

Revision 24605, 5.4 KB checked in by broder, 14 years ago (diff)
Snapshot new version of PyMoira that includes mrclient bindings.
Line 
1cdef extern from "moira/moira.h":
2    int mr_krb5_auth(char * prog)
3    int mr_auth(char * prog)
4    int mr_connect(char * server)
5    int mr_disconnect()
6    int mr_host(char * host_buf, int buf_size)
7    int mr_motd(char ** motd)
8    int mr_noop()
9    int mr_query(char * handle, int argc, char ** argv,
10                 int (*callback)(int, char **, void *), object callarg)
11    int mr_access(char *handle, int argc, char ** argv)
12    int mr_proxy(char *principal, char *orig_authtype)
13    int mr_version(int version)
14
15    enum:
16        MR_SUCCESS
17        MR_CONT
18
19        MR_VERSION_LOW
20
21cdef extern from "com_err.h":
22    ctypedef long errcode_t
23    char * error_message(errcode_t)
24
25cdef extern from "stdlib.h":
26    ctypedef unsigned long size_t
27    void * malloc(size_t size)
28    void free(void * ptr)
29
30class MoiraException(Exception):
31    def code(self):
32        return self.args[0]
33    code = property(code)
34
35__connected = False
36
37def _error(code):
38    raise MoiraException, (code, error_message(code))
39
40def connect(server=''):
41    """
42    Establish a connection to a Moira server.
43   
44    A server may be specified, but it is optional. If specified, it
45    should be of the form hostname:portname. Portname will be looked
46    up in /etc/services if specified, but it is optional as well.
47   
48    If no server is specified, the server will be found from the
49    MOIRASERVER environment variable, Hesiod, or a compiled in default
50    (in that order).
51   
52    This function raises a MoiraException if the connection is
53    not successful.
54    """
55    global __connected
56   
57    if __connected:
58        disconnect()
59   
60    status = mr_connect(server)
61    if status != MR_SUCCESS:
62        _error(status)
63    else:
64        __connected = True
65
66def disconnect():
67    """
68    Disconnect from the active Moira server
69    """
70    global __connected
71    if __connected:
72        mr_disconnect()
73    __connected = False
74
75def auth(program, krb4=False):
76    """
77    Authenticate to the Moira server with Kerberos tickets. If krb4 is
78    True, then Kerberos version 4 will be used. Otherwise, Kerberos
79    version 5 is used.
80   
81    The program argument identifies the connecting program to the
82    Moira server. This is used for setting the modwith field when
83    modifications are made.
84   
85    Note that the use of Kerberos version 4 is deprecated and highly
86    discouraged
87    """
88    if krb4:
89        status = mr_auth(program)
90    else:
91        status = mr_krb5_auth(program)
92    if status != MR_SUCCESS:
93        _error(status)
94
95def host():
96    """
97    Return the name of the host the client is connected to.
98    """
99    cdef char buffer[512]
100    status = mr_host(buffer, 512)
101    if status != MR_SUCCESS:
102        _error(status)
103    return buffer
104
105def motd():
106    """
107    Retrieve the current message of the day from the server.
108    """
109    cdef char * motd
110    status = mr_motd(&motd)
111    if status != MR_SUCCESS:
112        _error(status)
113    if motd != NULL:
114        return motd
115
116def noop():
117    """
118    Does "no operation" to the server, just making sure it's still
119    there
120    """
121    status = mr_noop()
122    if status:
123        _error(status)
124
125def _access(handle, *args):
126    """
127    Verifies that the authenticated user has the access to perform the
128    given query.
129    """
130    cdef int argc, i
131    argc = len(args)
132    cdef char ** argv
133    argv = <char **>malloc(argc * sizeof(char *))
134
135    if argv != NULL:
136        for i in xrange(argc):
137            argv[i] = args[i]
138
139        status = mr_access(handle, argc, argv)
140        free(argv)
141
142        if status:
143            _error(status)
144
145def _query(handle, callback, *args):
146    cdef int argc, i
147    argc = len(args)
148    cdef char ** argv
149    argv = <char **>malloc(argc * sizeof(char *))
150   
151    if argv != NULL:
152        for i in xrange(argc):
153            argv[i] = args[i]
154       
155        status = mr_query(handle, argc, argv, _call_python_callback, callback)
156        free(argv)
157       
158        if status:
159            _error(status)
160
161def proxy(principal, orig_authtype):
162    """
163    Authenticate as a proxy for another principal.
164
165    For those with sufficient privilege, proxy allows an authenticated
166    user to impersonate another.
167
168    The principal argument contains the Kerberos principal for which
169    this user is proxying, and orig_authtype is the mechanism by which
170    the proxied user originally authenticated to the proxier.
171    """
172    status = mr_proxy(principal, orig_authtype)
173    if status != MR_SUCCESS:
174        _error(status)
175
176def version(ver):
177    """
178    Exchange query version info with the server.
179
180    In order to allow changing queries without breaking client
181    compatibility, the Moira server supports multiple versions of the
182    query list simultaneously. Use version to change which one is
183    currently being used.
184
185    The ver argument is a signed integer containing the query version
186    to use. If ver is -1, Moira will always use the more recent query
187    version.
188
189    version returns True if you requested the most recent version
190    number and False if you requested an out-of-date version number.
191    """
192    status = mr_version(ver)
193    if status == MR_SUCCESS:
194        return True
195    elif status == MR_VERSION_LOW:
196        return False
197    else:
198        _error(status)
199
200cdef int _call_python_callback(int argc, char ** argv, void * hint):
201    cdef object callback
202    callback = <object>hint
203    result = []
204    cdef int i
205    for i in xrange(argc):
206        result.append(argv[i])
207    callback(tuple(result))
208    return MR_CONT
Note: See TracBrowser for help on using the repository browser.