Projet

Général

Profil

0001-Add-max-changes-and-force-parameters.patch

Benjamin Renard, 28 mars 2022 15:35

Télécharger (4,19 ko)

Voir les différences:

Subject: [PATCH] Add --max-changes and --force parameters

 src/ldaptools/ldapsync/cmd.py | 66 ++++++++++++++++++++++++++++++++++-
 1 file changed, 65 insertions(+), 1 deletion(-)
src/ldaptools/ldapsync/cmd.py
6 6
import ldap.sasl
7 7

  
8 8
from ldaptools import ldif_utils, paged, ldap_source
9
from ldaptools.synchronize import Synchronize
9
from ldaptools.synchronize import Synchronize, Create, Rename, Update, Delete
10

  
11

  
12
operation_types = {
13
    'create': Create,
14
    'rename': Rename,
15
    'update': Update,
16
    'delete': Delete,
17
}
10 18

  
11 19

  
12 20
def source_uri(value):
......
35 43
    return value
36 44

  
37 45

  
46
def max_changes_threshold(value):
47
    if ':' in value:
48
        try:
49
            operation_type, threshold = value.strip().split(':')
50
        except ValueError as exc:
51
            raise argparse.ArgumentTypeError(
52
                'Invalid operation threshold %s' % value) from exc
53
        if operation_type not in operation_types:
54
            raise argparse.ArgumentTypeError('Unknown %s operation type' % operation_type)
55
        operation_type = operation_types[operation_type]
56
    else:
57
        operation_type = None
58
        threshold = value
59
    try:
60
        threshold = int(threshold)
61
        if threshold < 1:
62
            raise ValueError
63
    except ValueError as exc:
64
        raise argparse.ArgumentTypeError(
65
            'Invalid threshold %s, must be a positive integer' % threshold) from exc
66
    return (operation_type, threshold)
67

  
68

  
38 69
def main(args=None):
39 70
    parser = argparse.ArgumentParser(description='''\
40 71
Synchronize an LDIF file or a source LDAP directory to another directory
......
84 115
    parser.add_argument('--fake',
85 116
                        action='store_true',
86 117
                        help='compute synchronization actions but do not apply')
118
    parser.add_argument(
119
        '--max-changes', type=max_changes_threshold, action='append',
120
        help=(
121
            'maximum changes count: permit to inhibit synchronization '
122
            'if too much changes are detected. You could specify a '
123
            'threshold by operation type (%s), for instance, '
124
            '"delete:10". To specify a global threshold, just specify '
125
            'the change count. You could specify multiple threshold '
126
            'by repeating this parameter.' % ', '.join(operation_types)
127
        ))
128
    parser.add_argument(
129
        '--force', action='store_true',
130
        help='Force synchronization, even if a threshold is reached.')
87 131
    parser.add_argument('--verbose',
88 132
                        action='store_true',
89 133
                        help='print all actions to stdout')
......
147 191
            print(' -', action)
148 192
        if not synchronize.actions:
149 193
            print('Nothing to do.')
194

  
195
    if options.max_changes:
196
        threshold_reached = False
197
        for operation_type, threshold in options.max_changes:
198
            count = len([
199
                action for action in synchronize.actions
200
                if not operation_type or isinstance(action, operation_type)
201
            ])
202
            if count > threshold:
203
                print(
204
                    'Max %soperation threshold reached (%d > %d)' % (
205
                        "%s " % operation_type.__name__.lower() if operation_type else '',
206
                        count, threshold))
207
                threshold_reached = True
208
        if threshold_reached:
209
            if not options.force:
210
                print('Block this synchronization. Run again with --force parameter to force.')
211
                sys.exit(2)
212
            print('Force mode, continue')
213

  
150 214
    if not options.fake:
151 215
        synchronize.apply_actions()
152 216
    failed_actions = [action for action in synchronize.actions if action.errors]
153
-