/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk

« back to all changes in this revision

Viewing changes to mandos-ctl

  • Committer: Teddy Hogeborn
  • Date: 2019-03-30 17:02:33 UTC
  • Revision ID: teddy@recompile.se-20190330170233-nxu3cgb98q2g3o5j
Fix typo in intro(8mandos).

* intro.xml (INTRODUCTION): Add missing period at end of last sentence
                            of penultimate paragraph.

Show diffs side-by-side

added added

removed removed

Lines of Context:
122
122
                        help="Select all clients")
123
123
    parser.add_argument("-v", "--verbose", action="store_true",
124
124
                        help="Print all fields")
125
 
    parser.add_argument("-j", "--dump-json", dest="commands",
126
 
                        action="append_const", default=[],
127
 
                        const=command.DumpJSON(),
 
125
    parser.add_argument("-j", "--dump-json", action="store_true",
128
126
                        help="Dump client data in JSON format")
129
127
    enable_disable = parser.add_mutually_exclusive_group()
130
 
    enable_disable.add_argument("-e", "--enable", dest="commands",
131
 
                                action="append_const", default=[],
132
 
                                const=command.Enable(),
 
128
    enable_disable.add_argument("-e", "--enable", action="store_true",
133
129
                                help="Enable client")
134
 
    enable_disable.add_argument("-d", "--disable", dest="commands",
135
 
                                action="append_const", default=[],
136
 
                                const=command.Disable(),
 
130
    enable_disable.add_argument("-d", "--disable",
 
131
                                action="store_true",
137
132
                                help="disable client")
138
 
    parser.add_argument("-b", "--bump-timeout", dest="commands",
139
 
                        action="append_const", default=[],
140
 
                        const=command.BumpTimeout(),
 
133
    parser.add_argument("-b", "--bump-timeout", action="store_true",
141
134
                        help="Bump timeout for client")
142
135
    start_stop_checker = parser.add_mutually_exclusive_group()
143
136
    start_stop_checker.add_argument("--start-checker",
144
 
                                    dest="commands",
145
 
                                    action="append_const", default=[],
146
 
                                    const=command.StartChecker(),
 
137
                                    action="store_true",
147
138
                                    help="Start checker for client")
148
 
    start_stop_checker.add_argument("--stop-checker", dest="commands",
149
 
                                    action="append_const", default=[],
150
 
                                    const=command.StopChecker(),
 
139
    start_stop_checker.add_argument("--stop-checker",
 
140
                                    action="store_true",
151
141
                                    help="Stop checker for client")
152
 
    parser.add_argument("-V", "--is-enabled", dest="commands",
153
 
                        action="append_const", default=[],
154
 
                        const=command.IsEnabled(),
 
142
    parser.add_argument("-V", "--is-enabled", action="store_true",
155
143
                        help="Check if client is enabled")
156
 
    parser.add_argument("-r", "--remove", dest="commands",
157
 
                        action="append_const", default=[],
158
 
                        const=command.Remove(),
 
144
    parser.add_argument("-r", "--remove", action="store_true",
159
145
                        help="Remove client")
160
 
    parser.add_argument("-c", "--checker", dest="commands",
161
 
                        action="append", default=[],
162
 
                        metavar="COMMAND", type=command.SetChecker,
 
146
    parser.add_argument("-c", "--checker",
163
147
                        help="Set checker command for client")
164
 
    parser.add_argument(
165
 
        "-t", "--timeout", dest="commands", action="append",
166
 
        default=[], metavar="TIME",
167
 
        type=command.SetTimeout.argparse(string_to_delta),
168
 
        help="Set timeout for client")
169
 
    parser.add_argument(
170
 
        "--extended-timeout", dest="commands", action="append",
171
 
        default=[], metavar="TIME",
172
 
        type=command.SetExtendedTimeout.argparse(string_to_delta),
173
 
        help="Set extended timeout for client")
174
 
    parser.add_argument(
175
 
        "-i", "--interval", dest="commands", action="append",
176
 
        default=[], metavar="TIME",
177
 
        type=command.SetInterval.argparse(string_to_delta),
178
 
        help="Set checker interval for client")
 
148
    parser.add_argument("-t", "--timeout", type=string_to_delta,
 
149
                        help="Set timeout for client")
 
150
    parser.add_argument("--extended-timeout", type=string_to_delta,
 
151
                        help="Set extended timeout for client")
 
152
    parser.add_argument("-i", "--interval", type=string_to_delta,
 
153
                        help="Set checker interval for client")
179
154
    approve_deny_default = parser.add_mutually_exclusive_group()
180
155
    approve_deny_default.add_argument(
181
 
        "--approve-by-default", dest="commands",
182
 
        action="append_const", default=[],
183
 
        const=command.ApproveByDefault(),
 
156
        "--approve-by-default", action="store_true",
 
157
        default=None, dest="approved_by_default",
184
158
        help="Set client to be approved by default")
185
159
    approve_deny_default.add_argument(
186
 
        "--deny-by-default", dest="commands",
187
 
        action="append_const", default=[],
188
 
        const=command.DenyByDefault(),
 
160
        "--deny-by-default", action="store_false",
 
161
        dest="approved_by_default",
189
162
        help="Set client to be denied by default")
190
 
    parser.add_argument(
191
 
        "--approval-delay", dest="commands", action="append",
192
 
        default=[], metavar="TIME",
193
 
        type=command.SetApprovalDelay.argparse(string_to_delta),
194
 
        help="Set delay before client approve/deny")
195
 
    parser.add_argument(
196
 
        "--approval-duration", dest="commands", action="append",
197
 
        default=[], metavar="TIME",
198
 
        type=command.SetApprovalDuration.argparse(string_to_delta),
199
 
        help="Set duration of one client approval")
200
 
    parser.add_argument("-H", "--host", dest="commands",
201
 
                        action="append", default=[], metavar="STRING",
202
 
                        type=command.SetHost,
203
 
                        help="Set host for client")
204
 
    parser.add_argument(
205
 
        "-s", "--secret", dest="commands", action="append",
206
 
        default=[], metavar="FILENAME",
207
 
        type=command.SetSecret.argparse(argparse.FileType(mode="rb")),
208
 
        help="Set password blob (file) for client")
 
163
    parser.add_argument("--approval-delay", type=string_to_delta,
 
164
                        help="Set delay before client approve/deny")
 
165
    parser.add_argument("--approval-duration", type=string_to_delta,
 
166
                        help="Set duration of one client approval")
 
167
    parser.add_argument("-H", "--host", help="Set host for client")
 
168
    parser.add_argument("-s", "--secret",
 
169
                        type=argparse.FileType(mode="rb"),
 
170
                        help="Set password blob (file) for client")
209
171
    approve_deny = parser.add_mutually_exclusive_group()
210
172
    approve_deny.add_argument(
211
 
        "-A", "--approve", dest="commands", action="append_const",
212
 
        default=[], const=command.Approve(),
 
173
        "-A", "--approve", action="store_true",
213
174
        help="Approve any current client request")
214
 
    approve_deny.add_argument("-D", "--deny", dest="commands",
215
 
                              action="append_const", default=[],
216
 
                              const=command.Deny(),
 
175
    approve_deny.add_argument("-D", "--deny", action="store_true",
217
176
                              help="Deny any current client request")
218
177
    parser.add_argument("--debug", action="store_true",
219
178
                        help="Debug mode (show D-Bus commands)")
410
369
    """Apply additional restrictions on options, not expressible in
411
370
argparse"""
412
371
 
413
 
    def has_commands(options, commands=None):
414
 
        if commands is None:
415
 
            commands = (command.Enable,
416
 
                        command.Disable,
417
 
                        command.BumpTimeout,
418
 
                        command.StartChecker,
419
 
                        command.StopChecker,
420
 
                        command.IsEnabled,
421
 
                        command.Remove,
422
 
                        command.SetChecker,
423
 
                        command.SetTimeout,
424
 
                        command.SetExtendedTimeout,
425
 
                        command.SetInterval,
426
 
                        command.ApproveByDefault,
427
 
                        command.DenyByDefault,
428
 
                        command.SetApprovalDelay,
429
 
                        command.SetApprovalDuration,
430
 
                        command.SetHost,
431
 
                        command.SetSecret,
432
 
                        command.Approve,
433
 
                        command.Deny)
434
 
        return any(isinstance(cmd, commands)
435
 
                   for cmd in options.commands)
 
372
    def has_actions(options):
 
373
        return any((options.enable,
 
374
                    options.disable,
 
375
                    options.bump_timeout,
 
376
                    options.start_checker,
 
377
                    options.stop_checker,
 
378
                    options.is_enabled,
 
379
                    options.remove,
 
380
                    options.checker is not None,
 
381
                    options.timeout is not None,
 
382
                    options.extended_timeout is not None,
 
383
                    options.interval is not None,
 
384
                    options.approved_by_default is not None,
 
385
                    options.approval_delay is not None,
 
386
                    options.approval_duration is not None,
 
387
                    options.host is not None,
 
388
                    options.secret is not None,
 
389
                    options.approve,
 
390
                    options.deny))
436
391
 
437
 
    if has_commands(options) and not (options.client or options.all):
 
392
    if has_actions(options) and not (options.client or options.all):
438
393
        parser.error("Options require clients names or --all.")
439
 
    if options.verbose and has_commands(options):
 
394
    if options.verbose and has_actions(options):
440
395
        parser.error("--verbose can only be used alone.")
441
 
    if (has_commands(options, (command.DumpJSON,))
442
 
        and (options.verbose or len(options.commands) > 1)):
 
396
    if options.dump_json and (options.verbose
 
397
                              or has_actions(options)):
443
398
        parser.error("--dump-json can only be used alone.")
444
 
    if options.all and not has_commands(options):
 
399
    if options.all and not has_actions(options):
445
400
        parser.error("--all requires an action.")
446
 
    if (has_commands(options, (command.IsEnabled,))
447
 
        and len(options.client) > 1):
 
401
    if options.is_enabled and len(options.client) > 1:
448
402
        parser.error("--is-enabled requires exactly one client")
449
 
    if (len(options.commands) > 1
450
 
        and has_commands(options, (command.Remove,))
451
 
        and not has_commands(options, (command.Deny,))):
452
 
        parser.error("--remove can only be combined with --deny")
 
403
    if options.remove:
 
404
        options.remove = False
 
405
        if has_actions(options) and not options.deny:
 
406
            parser.error("--remove can only be combined with --deny")
 
407
        options.remove = True
 
408
 
453
409
 
454
410
 
455
411
class dbus(object):
595
551
 
596
552
def commands_from_options(options):
597
553
 
598
 
    commands = list(options.commands)
599
 
 
600
 
    def find_cmd(cmd, commands):
601
 
        i = 0
602
 
        for i, c in enumerate(commands):
603
 
            if isinstance(c, cmd):
604
 
                return i
605
 
        return i+1
606
 
 
607
 
    # If command.Remove is present, move any instances of command.Deny
608
 
    # to occur ahead of command.Remove.
609
 
    index_of_remove = find_cmd(command.Remove, commands)
610
 
    before_remove = commands[:index_of_remove]
611
 
    after_remove = commands[index_of_remove:]
612
 
    cleaned_after = []
613
 
    for cmd in after_remove:
614
 
        if isinstance(cmd, command.Deny):
615
 
            before_remove.append(cmd)
 
554
    commands = []
 
555
 
 
556
    if options.is_enabled:
 
557
        commands.append(command.IsEnabled())
 
558
 
 
559
    if options.approve:
 
560
        commands.append(command.Approve())
 
561
 
 
562
    if options.deny:
 
563
        commands.append(command.Deny())
 
564
 
 
565
    if options.remove:
 
566
        commands.append(command.Remove())
 
567
 
 
568
    if options.dump_json:
 
569
        commands.append(command.DumpJSON())
 
570
 
 
571
    if options.enable:
 
572
        commands.append(command.Enable())
 
573
 
 
574
    if options.disable:
 
575
        commands.append(command.Disable())
 
576
 
 
577
    if options.bump_timeout:
 
578
        commands.append(command.BumpTimeout())
 
579
 
 
580
    if options.start_checker:
 
581
        commands.append(command.StartChecker())
 
582
 
 
583
    if options.stop_checker:
 
584
        commands.append(command.StopChecker())
 
585
 
 
586
    if options.approved_by_default is not None:
 
587
        if options.approved_by_default:
 
588
            commands.append(command.ApproveByDefault())
616
589
        else:
617
 
            cleaned_after.append(cmd)
618
 
    if cleaned_after != after_remove:
619
 
        commands = before_remove + cleaned_after
 
590
            commands.append(command.DenyByDefault())
 
591
 
 
592
    if options.checker is not None:
 
593
        commands.append(command.SetChecker(options.checker))
 
594
 
 
595
    if options.host is not None:
 
596
        commands.append(command.SetHost(options.host))
 
597
 
 
598
    if options.secret is not None:
 
599
        commands.append(command.SetSecret(options.secret))
 
600
 
 
601
    if options.timeout is not None:
 
602
        commands.append(command.SetTimeout(options.timeout))
 
603
 
 
604
    if options.extended_timeout:
 
605
        commands.append(
 
606
            command.SetExtendedTimeout(options.extended_timeout))
 
607
 
 
608
    if options.interval is not None:
 
609
        commands.append(command.SetInterval(options.interval))
 
610
 
 
611
    if options.approval_delay is not None:
 
612
        commands.append(
 
613
            command.SetApprovalDelay(options.approval_delay))
 
614
 
 
615
    if options.approval_duration is not None:
 
616
        commands.append(
 
617
            command.SetApprovalDuration(options.approval_duration))
620
618
 
621
619
    # If no command option has been given, show table of clients,
622
620
    # optionally verbosely
837
835
        def __init__(self, value):
838
836
            self.value_to_set = value
839
837
 
840
 
        @classmethod
841
 
        def argparse(cls, argtype):
842
 
            def cmdtype(arg):
843
 
                return cls(argtype(arg))
844
 
            return cmdtype
845
838
 
846
839
    class SetChecker(PropertySetterValue):
847
840
        propname = "Checker"
973
966
 
974
967
    def test_actions_requires_client_or_all(self):
975
968
        for action, value in self.actions.items():
976
 
            args = self.actionargs(action, value)
 
969
            options = self.parser.parse_args()
 
970
            setattr(options, action, value)
977
971
            with self.assertParseError():
978
 
                self.parse_args(args)
 
972
                self.check_option_syntax(options)
979
973
 
980
 
    # This mostly corresponds to the definition from has_commands() in
 
974
    # This mostly corresponds to the definition from has_actions() in
981
975
    # check_option_syntax()
982
976
    actions = {
983
 
        "--enable": None,
984
 
        "--disable": None,
985
 
        "--bump-timeout": None,
986
 
        "--start-checker": None,
987
 
        "--stop-checker": None,
988
 
        "--is-enabled": None,
989
 
        "--remove": None,
990
 
        "--checker": "x",
991
 
        "--timeout": "PT0S",
992
 
        "--extended-timeout": "PT0S",
993
 
        "--interval": "PT0S",
994
 
        "--approve-by-default": None,
995
 
        "--deny-by-default": None,
996
 
        "--approval-delay": "PT0S",
997
 
        "--approval-duration": "PT0S",
998
 
        "--host": "hostname",
999
 
        "--secret": "/dev/null",
1000
 
        "--approve": None,
1001
 
        "--deny": None,
 
977
        # The actual values set here are not that important, but we do
 
978
        # at least stick to the correct types, even though they are
 
979
        # never used
 
980
        "enable": True,
 
981
        "disable": True,
 
982
        "bump_timeout": True,
 
983
        "start_checker": True,
 
984
        "stop_checker": True,
 
985
        "is_enabled": True,
 
986
        "remove": True,
 
987
        "checker": "x",
 
988
        "timeout": datetime.timedelta(),
 
989
        "extended_timeout": datetime.timedelta(),
 
990
        "interval": datetime.timedelta(),
 
991
        "approved_by_default": True,
 
992
        "approval_delay": datetime.timedelta(),
 
993
        "approval_duration": datetime.timedelta(),
 
994
        "host": "x",
 
995
        "secret": io.BytesIO(b"x"),
 
996
        "approve": True,
 
997
        "deny": True,
1002
998
    }
1003
999
 
1004
 
    @staticmethod
1005
 
    def actionargs(action, value, *args):
1006
 
        if value is not None:
1007
 
            return [action, value] + list(args)
1008
 
        else:
1009
 
            return [action] + list(args)
1010
 
 
1011
1000
    @contextlib.contextmanager
1012
1001
    def assertParseError(self):
1013
1002
        with self.assertRaises(SystemExit) as e:
1018
1007
        # /argparse.html#exiting-methods
1019
1008
        self.assertEqual(2, e.exception.code)
1020
1009
 
1021
 
    def parse_args(self, args):
1022
 
        options = self.parser.parse_args(args)
1023
 
        check_option_syntax(self.parser, options)
1024
 
 
1025
1010
    @staticmethod
1026
1011
    @contextlib.contextmanager
1027
1012
    def redirect_stderr_to_devnull():
1038
1023
 
1039
1024
    def test_actions_all_conflicts_with_verbose(self):
1040
1025
        for action, value in self.actions.items():
1041
 
            args = self.actionargs(action, value, "--all",
1042
 
                                   "--verbose")
 
1026
            options = self.parser.parse_args()
 
1027
            setattr(options, action, value)
 
1028
            options.all = True
 
1029
            options.verbose = True
1043
1030
            with self.assertParseError():
1044
 
                self.parse_args(args)
 
1031
                self.check_option_syntax(options)
1045
1032
 
1046
1033
    def test_actions_with_client_conflicts_with_verbose(self):
1047
1034
        for action, value in self.actions.items():
1048
 
            args = self.actionargs(action, value, "--verbose",
1049
 
                                   "client")
 
1035
            options = self.parser.parse_args()
 
1036
            setattr(options, action, value)
 
1037
            options.verbose = True
 
1038
            options.client = ["client"]
1050
1039
            with self.assertParseError():
1051
 
                self.parse_args(args)
 
1040
                self.check_option_syntax(options)
1052
1041
 
1053
1042
    def test_dump_json_conflicts_with_verbose(self):
1054
 
        args = ["--dump-json", "--verbose"]
 
1043
        options = self.parser.parse_args()
 
1044
        options.dump_json = True
 
1045
        options.verbose = True
1055
1046
        with self.assertParseError():
1056
 
            self.parse_args(args)
 
1047
            self.check_option_syntax(options)
1057
1048
 
1058
1049
    def test_dump_json_conflicts_with_action(self):
1059
1050
        for action, value in self.actions.items():
1060
 
            args = self.actionargs(action, value, "--dump-json")
 
1051
            options = self.parser.parse_args()
 
1052
            setattr(options, action, value)
 
1053
            options.dump_json = True
1061
1054
            with self.assertParseError():
1062
 
                self.parse_args(args)
 
1055
                self.check_option_syntax(options)
1063
1056
 
1064
1057
    def test_all_can_not_be_alone(self):
1065
 
        args = ["--all"]
 
1058
        options = self.parser.parse_args()
 
1059
        options.all = True
1066
1060
        with self.assertParseError():
1067
 
            self.parse_args(args)
 
1061
            self.check_option_syntax(options)
1068
1062
 
1069
1063
    def test_all_is_ok_with_any_action(self):
1070
1064
        for action, value in self.actions.items():
1071
 
            args = self.actionargs(action, value, "--all")
1072
 
            self.parse_args(args)
 
1065
            options = self.parser.parse_args()
 
1066
            setattr(options, action, value)
 
1067
            options.all = True
 
1068
            self.check_option_syntax(options)
1073
1069
 
1074
1070
    def test_any_action_is_ok_with_one_client(self):
1075
1071
        for action, value in self.actions.items():
1076
 
            args = self.actionargs(action, value, "client")
1077
 
            self.parse_args(args)
 
1072
            options = self.parser.parse_args()
 
1073
            setattr(options, action, value)
 
1074
            options.client = ["client"]
 
1075
            self.check_option_syntax(options)
1078
1076
 
1079
1077
    def test_one_client_with_all_actions_except_is_enabled(self):
 
1078
        options = self.parser.parse_args()
1080
1079
        for action, value in self.actions.items():
1081
 
            if action == "--is-enabled":
 
1080
            if action == "is_enabled":
1082
1081
                continue
1083
 
            args = self.actionargs(action, value, "client")
1084
 
            self.parse_args(args)
 
1082
            setattr(options, action, value)
 
1083
        options.client = ["client"]
 
1084
        self.check_option_syntax(options)
1085
1085
 
1086
1086
    def test_two_clients_with_all_actions_except_is_enabled(self):
 
1087
        options = self.parser.parse_args()
1087
1088
        for action, value in self.actions.items():
1088
 
            if action == "--is-enabled":
 
1089
            if action == "is_enabled":
1089
1090
                continue
1090
 
            args = self.actionargs(action, value, "client1",
1091
 
                                   "client2")
1092
 
            self.parse_args(args)
 
1091
            setattr(options, action, value)
 
1092
        options.client = ["client1", "client2"]
 
1093
        self.check_option_syntax(options)
1093
1094
 
1094
1095
    def test_two_clients_are_ok_with_actions_except_is_enabled(self):
1095
1096
        for action, value in self.actions.items():
1096
 
            if action == "--is-enabled":
 
1097
            if action == "is_enabled":
1097
1098
                continue
1098
 
            args = self.actionargs(action, value, "client1",
1099
 
                                   "client2")
1100
 
            self.parse_args(args)
 
1099
            options = self.parser.parse_args()
 
1100
            setattr(options, action, value)
 
1101
            options.client = ["client1", "client2"]
 
1102
            self.check_option_syntax(options)
1101
1103
 
1102
1104
    def test_is_enabled_fails_without_client(self):
1103
 
        args = ["--is-enabled"]
 
1105
        options = self.parser.parse_args()
 
1106
        options.is_enabled = True
1104
1107
        with self.assertParseError():
1105
 
            self.parse_args(args)
 
1108
            self.check_option_syntax(options)
1106
1109
 
1107
1110
    def test_is_enabled_fails_with_two_clients(self):
1108
 
        args = ["--is-enabled", "client1", "client2"]
 
1111
        options = self.parser.parse_args()
 
1112
        options.is_enabled = True
 
1113
        options.client = ["client1", "client2"]
1109
1114
        with self.assertParseError():
1110
 
            self.parse_args(args)
 
1115
            self.check_option_syntax(options)
1111
1116
 
1112
1117
    def test_remove_can_only_be_combined_with_action_deny(self):
1113
1118
        for action, value in self.actions.items():
1114
 
            if action in {"--remove", "--deny"}:
 
1119
            if action in {"remove", "deny"}:
1115
1120
                continue
1116
 
            args = self.actionargs(action, value, "--all",
1117
 
                                   "--remove")
 
1121
            options = self.parser.parse_args()
 
1122
            setattr(options, action, value)
 
1123
            options.all = True
 
1124
            options.remove = True
1118
1125
            with self.assertParseError():
1119
 
                self.parse_args(args)
 
1126
                self.check_option_syntax(options)
1120
1127
 
1121
1128
 
1122
1129
class Test_dbus_exceptions(unittest.TestCase):
2063
2070
    def runTest(self):
2064
2071
        if not hasattr(self, "command"):
2065
2072
            return              # Abstract TestCase class
2066
 
 
2067
 
        if hasattr(self, "values_to_set"):
2068
 
            cmd_args = [(value,) for value in self.values_to_set]
2069
 
            values_to_get = getattr(self, "values_to_get",
2070
 
                                    self.values_to_set)
2071
 
        else:
2072
 
            cmd_args = [() for x in range(len(self.values_to_get))]
2073
 
            values_to_get = self.values_to_get
2074
 
        for value_to_get, cmd_arg in zip(values_to_get, cmd_args):
2075
 
            for clientpath in self.bus.clients:
2076
 
                self.bus.clients[clientpath][self.propname] = (
2077
 
                    Unique())
2078
 
            self.command(*cmd_arg).run(self.bus.clients, self.bus)
2079
 
            for clientpath in self.bus.clients:
2080
 
                value = (self.bus.clients[clientpath]
2081
 
                         [self.propname])
 
2073
        values_to_get = getattr(self, "values_to_get",
 
2074
                                self.values_to_set)
 
2075
        for value_to_set, value_to_get in zip(self.values_to_set,
 
2076
                                              values_to_get):
 
2077
            for clientpath in self.bus.clients:
 
2078
                self.bus.clients[clientpath][self.propname] = Unique()
 
2079
            self.run_command(value_to_set, self.bus.clients)
 
2080
            for clientpath in self.bus.clients:
 
2081
                value = self.bus.clients[clientpath][self.propname]
2082
2082
                self.assertNotIsInstance(value, Unique)
2083
2083
                self.assertEqual(value_to_get, value)
2084
2084
 
 
2085
    def run_command(self, value, clients):
 
2086
        self.command().run(clients, self.bus)
 
2087
 
2085
2088
 
2086
2089
class TestEnableCmd(TestPropertySetterCmd):
2087
2090
    command = command.Enable
2088
2091
    propname = "Enabled"
2089
 
    values_to_get = [True]
 
2092
    values_to_set = [True]
2090
2093
 
2091
2094
 
2092
2095
class TestDisableCmd(TestPropertySetterCmd):
2093
2096
    command = command.Disable
2094
2097
    propname = "Enabled"
2095
 
    values_to_get = [False]
 
2098
    values_to_set = [False]
2096
2099
 
2097
2100
 
2098
2101
class TestBumpTimeoutCmd(TestPropertySetterCmd):
2099
2102
    command = command.BumpTimeout
2100
2103
    propname = "LastCheckedOK"
2101
 
    values_to_get = [""]
 
2104
    values_to_set = [""]
2102
2105
 
2103
2106
 
2104
2107
class TestStartCheckerCmd(TestPropertySetterCmd):
2105
2108
    command = command.StartChecker
2106
2109
    propname = "CheckerRunning"
2107
 
    values_to_get = [True]
 
2110
    values_to_set = [True]
2108
2111
 
2109
2112
 
2110
2113
class TestStopCheckerCmd(TestPropertySetterCmd):
2111
2114
    command = command.StopChecker
2112
2115
    propname = "CheckerRunning"
2113
 
    values_to_get = [False]
 
2116
    values_to_set = [False]
2114
2117
 
2115
2118
 
2116
2119
class TestApproveByDefaultCmd(TestPropertySetterCmd):
2117
2120
    command = command.ApproveByDefault
2118
2121
    propname = "ApprovedByDefault"
2119
 
    values_to_get = [True]
 
2122
    values_to_set = [True]
2120
2123
 
2121
2124
 
2122
2125
class TestDenyByDefaultCmd(TestPropertySetterCmd):
2123
2126
    command = command.DenyByDefault
2124
2127
    propname = "ApprovedByDefault"
2125
 
    values_to_get = [False]
2126
 
 
2127
 
 
2128
 
class TestSetCheckerCmd(TestPropertySetterCmd):
 
2128
    values_to_set = [False]
 
2129
 
 
2130
 
 
2131
class TestPropertySetterValueCmd(TestPropertySetterCmd):
 
2132
    """Abstract class for tests of PropertySetterValueCmd classes"""
 
2133
 
 
2134
    def run_command(self, value, clients):
 
2135
        self.command(value).run(clients, self.bus)
 
2136
 
 
2137
 
 
2138
class TestSetCheckerCmd(TestPropertySetterValueCmd):
2129
2139
    command = command.SetChecker
2130
2140
    propname = "Checker"
2131
2141
    values_to_set = ["", ":", "fping -q -- %s"]
2132
2142
 
2133
2143
 
2134
 
class TestSetHostCmd(TestPropertySetterCmd):
 
2144
class TestSetHostCmd(TestPropertySetterValueCmd):
2135
2145
    command = command.SetHost
2136
2146
    propname = "Host"
2137
2147
    values_to_set = ["192.0.2.3", "client.example.org"]
2138
2148
 
2139
2149
 
2140
 
class TestSetSecretCmd(TestPropertySetterCmd):
 
2150
class TestSetSecretCmd(TestPropertySetterValueCmd):
2141
2151
    command = command.SetSecret
2142
2152
    propname = "Secret"
2143
2153
    values_to_set = [io.BytesIO(b""),
2145
2155
    values_to_get = [f.getvalue() for f in values_to_set]
2146
2156
 
2147
2157
 
2148
 
class TestSetTimeoutCmd(TestPropertySetterCmd):
 
2158
class TestSetTimeoutCmd(TestPropertySetterValueCmd):
2149
2159
    command = command.SetTimeout
2150
2160
    propname = "Timeout"
2151
2161
    values_to_set = [datetime.timedelta(),
2156
2166
    values_to_get = [dt.total_seconds()*1000 for dt in values_to_set]
2157
2167
 
2158
2168
 
2159
 
class TestSetExtendedTimeoutCmd(TestPropertySetterCmd):
 
2169
class TestSetExtendedTimeoutCmd(TestPropertySetterValueCmd):
2160
2170
    command = command.SetExtendedTimeout
2161
2171
    propname = "ExtendedTimeout"
2162
2172
    values_to_set = [datetime.timedelta(),
2167
2177
    values_to_get = [dt.total_seconds()*1000 for dt in values_to_set]
2168
2178
 
2169
2179
 
2170
 
class TestSetIntervalCmd(TestPropertySetterCmd):
 
2180
class TestSetIntervalCmd(TestPropertySetterValueCmd):
2171
2181
    command = command.SetInterval
2172
2182
    propname = "Interval"
2173
2183
    values_to_set = [datetime.timedelta(),
2178
2188
    values_to_get = [dt.total_seconds()*1000 for dt in values_to_set]
2179
2189
 
2180
2190
 
2181
 
class TestSetApprovalDelayCmd(TestPropertySetterCmd):
 
2191
class TestSetApprovalDelayCmd(TestPropertySetterValueCmd):
2182
2192
    command = command.SetApprovalDelay
2183
2193
    propname = "ApprovalDelay"
2184
2194
    values_to_set = [datetime.timedelta(),
2189
2199
    values_to_get = [dt.total_seconds()*1000 for dt in values_to_set]
2190
2200
 
2191
2201
 
2192
 
class TestSetApprovalDurationCmd(TestPropertySetterCmd):
 
2202
class TestSetApprovalDurationCmd(TestPropertySetterValueCmd):
2193
2203
    command = command.SetApprovalDuration
2194
2204
    propname = "ApprovalDuration"
2195
2205
    values_to_set = [datetime.timedelta(),