root/livinglogic.python.xist/src/ll/orasql/scripts/oragrant.py @ 4519:c4c0660af381

Revision 4519:c4c0660af381, 6.1 KB (checked in by Walter Doerwald <walter@…>, 8 years ago)

Added options --include and --exclude to oracreate, oradrop and oragrant.

Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4## Copyright 2005-2011 by LivingLogic AG, Bayreuth/Germany.
5## Copyright 2005-2011 by Walter Dörwald
6##
7## All Rights Reserved
8##
9## See orasql/__init__.py for the license
10
11
12"""
13Purpose
14-------
15
16``oragrant`` prints all existing grants in an Oracle database schema.
17It can also be used to execute these grant statements directly.
18
19
20Options
21-------
22
23``oragrant`` supports the following options:
24
25    ``connectstring``
26        An Oracle connectstring.
27
28    ``-v``, ``--verbose`` : ``false``, ``no``, ``0``, ``true``, ``yes`` or ``1``
29        Produces output (on stderr) while to database is read or written.
30
31    ``-c``, ``--color`` : ``yes``, ``no`` or ``auto``
32        Should the output (when the ``-v`` option is used) be colored. If ``auto``
33        is specified (the default) then the output is colored if stderr is a
34        terminal.
35
36    ``-x``, ``--execute`` : connectstring
37        When the ``-x`` argument is given the SQL script isn't printed on stdout,
38        but executed in the database specfied as the ``-x`` argument.
39
40    ``-k``, ``--keepjunk`` : ``false``, ``no``, ``0``, ``true``, ``yes`` or ``1``
41        If true (the default), database objects that have ``$`` or
42        ``SYS_EXPORT_SCHEMA_`` in their name will be skipped (otherwise these
43        objects will be included in the output).
44
45    ``-i``, ``--ignore`` : ``false``, ``no``, ``0``, ``true``, ``yes`` or ``1``
46        If true, errors occuring while the database is read or written will be
47        ignored.
48
49    ``-m``, ``--mapgrantee`` : Python expression: ``list`` or ``dict``
50        A Python ``dict`` or ``list`` literal which will be evaluated. If the
51        grantee is not in this list (or dictionary) no grant statement will be
52        returned. If it's a dictionary and the grantee exists as a key, the
53        privilege will be granted to the user specified as the value instead of
54        the original one. The default is to grant all privileges to the original
55        grantee.
56
57    ``-e``, ``--encoding`` : encoding
58        The encoding of the output (if ``-x`` is not given; default is ``utf-8``).
59
60    ``--include`` : regexp
61        Only include objects in the output if their name contains the regular
62        expression.
63
64    ``--exclude`` : regexp
65        Exclude objects from the output if their name contains the regular
66        expression.
67
68
69Example
70-------
71
72Grant all privileges that ``alice`` has in the schema ``user@db`` to ``bob`` in
73``user2@db2``::
74
75    $ oragrant user/pwd@db -x user2/pwd2@db2 -m '{"alice": "bob"}' -v
76"""
77
78
79import sys, os, re, argparse
80
81from ll import misc, astyle, orasql
82
83
84__docformat__ = "reStructuredText"
85
86
87s4warning = astyle.Style.fromenv("LL_ORASQL_REPRANSI_WARNING", "red:black")
88s4error = astyle.Style.fromenv("LL_ORASQL_REPRANSI_ERROR", "red:black")
89s4connectstring = astyle.Style.fromenv("LL_ORASQL_REPRANSI_CONNECTSTRING", "yellow:black")
90s4object = astyle.Style.fromenv("LL_ORASQL_REPRANSI_OBJECT", "green:black")
91
92
93def main(args=None):
94    p = argparse.ArgumentParser(description="Print (and execute) grants statements from an Oracle database schema", epilog="For more info see http://www.livinglogic.de/Python/orasql/scripts/oragrant.html")
95    p.add_argument("connectstring", help="Oracle connect string")
96    p.add_argument("-v", "--verbose", dest="verbose", help="Give a progress report? (default %(default)s)", default=False, action=misc.FlagAction)
97    p.add_argument("-c", "--color", dest="color", help="Color output (default %(default)s)", default="auto", choices=("yes", "no", "auto"))
98    p.add_argument("-x", "--execute", metavar="CONNECTSTRING2", dest="execute", help="Execute in target database")
99    p.add_argument("-k", "--keepjunk", dest="keepjunk", help="Output objects with '$' or 'SYS_EXPORT_SCHEMA_' in their name? (default %(default)s)", default=False, action="store_true")
100    p.add_argument("-i", "--ignore", dest="ignore", help="Ignore errors? (default %(default)s)", default=False, action=misc.FlagAction)
101    p.add_argument("-m", "--mapgrantee", dest="mapgrantee", help="Map grantees (Python expression: list or dict)", default="True")
102    p.add_argument("-e", "--encoding", dest="encoding", help="Encoding for output (default %(default)s)", default="utf-8")
103    p.add_argument(      "--include", dest="include", metavar="REGEXP", help="Include only objects whose name contains PATTERN (default: %(default)s)", type=re.compile)
104    p.add_argument(      "--exclude", dest="exclude", metavar="REGEXP", help="Exclude objects whose name contains PATTERN (default: %(default)s)", type=re.compile)
105
106    args = p.parse_args(args)
107
108    if args.color == "yes":
109        color = True
110    elif args.color == "no":
111        color = False
112    else:
113        color = None
114    stdout = astyle.Stream(sys.stdout, color)
115    stderr = astyle.Stream(sys.stderr, color)
116
117    connection = orasql.connect(args.connectstring)
118
119    if args.execute:
120        connection2 = orasql.connect(args.execute)
121        cursor2 = connection2.cursor()
122        term = False
123    else:
124        term = True
125
126    cs1 = s4connectstring(connection.connectstring())
127    if args.execute:
128        cs2 = s4connectstring(connection2.connectstring())
129
130    mapgrantee = eval(args.mapgrantee)
131
132    def keep(obj):
133        if ("$" in obj.name or "/" in obj.name or obj.name.startswith("SYS_EXPORT_SCHEMA_")) and not args.keepjunk:
134            return False
135        if args.include is not None and args.include.search(obj.name) is None:
136            return False
137        if args.exclude is not None and args.exclude.search(obj.name) is not None:
138            return False
139        return True
140
141    for (i, obj) in enumerate(connection.iterprivileges(None)):
142        keepobj = keep(obj)
143        if args.verbose:
144            if args.execute:
145                msg = astyle.style_default("oragrant.py: ", cs1, " -> ", cs2, ": fetching/granting #{}".format(i+1))
146            else:
147                msg = astyle.style_default("oragrant.py: ", cs1, " fetching #{}".format(i+1))
148            msg = astyle.style_default(msg, " ", s4object(str(obj)))
149            if not keepobj:
150                msg = astyle.style_default(msg, " ", s4warning("(skipped)"))
151            stderr.writeln(msg)
152
153        if keepobj:
154            ddl = obj.grantddl(connection, term, mapgrantee=mapgrantee)
155            if ddl:
156                if args.execute:
157                    try:
158                        cursor2.execute(ddl)
159                    except orasql.DatabaseError, exc:
160                        if not args.ignore or "ORA-01013" in str(exc):
161                            raise
162                        stderr.writeln("oragrant.py: ", s4error("{}: {}".format(exc.__class__.__name__, str(exc).strip())))
163                else:
164                    stdout.writeln(ddl.encode(args.encoding))
165                    stdout.writeln()
166
167
168if __name__ == "__main__":
169    sys.exit(main())
Note: See TracBrowser for help on using the browser.