Skip to content

Commit 9696a83

Browse files
committed
fix #299: allow specifying command-line values using config file
This required a number of coordinated changes to app startup: - Argument processing (not parsing) was moved to the config module, including the expansion of the `mapped` users option the actual directory groups. - Separation was done of bootstrap options, invocation options, and rule-processing options, so each could be given a single point of definition with app defaults. - A new, optional `invocation_defaults` section was added to the main configuration file so the default values for all arguments could be specified there. These changes led to resolution to a number of long-standing issues: - There are no longer duplicate places where options have to be specified to get them added as rule-processing options and/or command-line arguments. - The top-level logic doesn't get involved with the interaction of command-line arguments and configuration files, or be sensitive to the timing of configuration loading and argument processing. - The logging of invocation now shows both the command-line arguments and their actual effect on the invocation options (including the formerly-hidden invocation options that actually override rule processing defaults). - The names of various internal options are now matched to the names of the command-line arguments that override them, so the code is more readable throughout.
1 parent 370d230 commit 9696a83

File tree

8 files changed

+546
-399
lines changed

8 files changed

+546
-399
lines changed

examples/config files - basic/1 user-sync-config.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,65 @@
88
# this sample and then customizing it. Feel free to remove extraneous commentary
99
# when you do your customization; doing so can greatly increase legibility.
1010

11+
# The invocation_defaults section controls the default values used
12+
# for command-line arguments. (Of course, these cannot be used to
13+
# change defaults for how the configuration files are read.) This
14+
# entire section is optional, as are each of its entries. But once
15+
# you standardize on specific argument values for all your runs,
16+
# putting them here can be an easy way to reliably use them, even
17+
# when running interactively rather than from a script.
18+
#
19+
# For arguments that take multiple arguments, such as --connector
20+
# and --users, the two-argument case should be specified as a list,
21+
# either using yaml compact notation:
22+
# connector: [csv, users-file.csv]
23+
# or using yaml multi-line notation:
24+
# connector:
25+
# - csv
26+
# - users-file.csv
27+
# The one-argument case can either use a string:
28+
# connector: ldap
29+
# or a compact list of one value:
30+
# connector: [ldap]
31+
# or a multi-line list of one value:
32+
# connector:
33+
# - ldap
34+
#
35+
# For arguments that are booleans, yaml syntax allows specifying their
36+
# default values using either True/False or Yes/No (case insensitive).
37+
#
38+
# If you specify filenames as part of your default values, they
39+
# are treated as if they were specified on the command line; that is,
40+
# they are interpreted relative to the User Sync current directory
41+
# (rather than the directory containing the configuration file).
42+
invocation_defaults:
43+
# For argument --adobe-only-user-action, the default is 'preserve'.
44+
adobe_only_user_action: preserve
45+
# For argument --adobe-only-user-list, the default is empty (no value).
46+
adobe_only_user_list:
47+
# For argument --connector, the default is 'ldap'.
48+
connector: ldap
49+
# For argument --process-groups, the default is False (don't process).
50+
# If you set this default to True, you can supply the argument
51+
# --no-process-groups to override the default.
52+
process_groups: No
53+
# For argument --strategy, the default is 'sync'.
54+
strategy: sync
55+
# For argument --test-mode (or -t), the default is False (live run).
56+
# if you set this default to True, you can supply the argument
57+
# --no-test-mode (or -T) to override the default.
58+
test_mode: No
59+
# For argument --update-user-info, the default is False (don't update).
60+
# If you set this default to True, you can supply the argument
61+
# --no-update-user-info to override the default.
62+
update_user_info: No
63+
# For argument --user-filter, the default is empty (no value).
64+
# Because regular expression notation uses special characters,
65+
# any default you set should almost certainly be single-quoted.
66+
user_filter:
67+
# For argument --users, the default is 'all'.
68+
users: all
69+
1170
# The adobe_users section controls connection to the Adobe UM API endpoints
1271
# and also which users on the Adobe side are eligible to be updated.
1372
adobe_users:

tests/connector/directory_okta_test.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ def test_found_user_single_group(self, mock_members):
161161
test_user = tests.helper.create_test_user_uid()
162162
mock_members.return_value = [test_user]
163163
directory = self.directory
164-
results = directory.load_users_and_groups(groups, [])
164+
results = directory.load_users_and_groups(groups, [], False)
165165
self.assertEqual(len(list(results)), 1)
166166

167167
@mock.patch('user_sync.connector.directory_okta.OktaDirectoryConnector.iter_group_members')
@@ -173,7 +173,7 @@ def test_found_user_multiple_groups(self, mock_members):
173173
test_users.append([tests.helper.create_test_user_uid()])
174174
mock_members.side_effect = test_users
175175
directory = self.directory
176-
results = directory.load_users_and_groups(groups, [])
176+
results = directory.load_users_and_groups(groups, [], False)
177177
self.assertEqual(len(list(results)), 2)
178178

179179
@mock.patch('user_sync.connector.directory_okta.OktaDirectoryConnector.iter_group_members')
@@ -187,7 +187,7 @@ def test_found_user_single_group_multiple_user(self, mock_members):
187187
user_count = user_count + 1
188188
mock_members.return_value = test_users
189189
directory = self.directory
190-
results = directory.load_users_and_groups(groups, [])
190+
results = directory.load_users_and_groups(groups, [], False)
191191
self.assertEqual(len(list(results)), 5)
192192

193193
@mock.patch('user_sync.connector.directory_okta.OktaDirectoryConnector.iter_group_members')
@@ -204,7 +204,7 @@ def test_found_user_multiple_groups_multiple_user(self, mock_members):
204204
total_test_users.append(test_users)
205205
mock_members.side_effect = total_test_users
206206
directory = self.directory
207-
results = directory.load_users_and_groups(groups, [])
207+
results = directory.load_users_and_groups(groups, [], False)
208208
self.assertEqual(len(list(results)), 10)
209209

210210
@mock.patch('user_sync.connector.directory_okta.OktaDirectoryConnector.iter_group_members')
@@ -214,7 +214,7 @@ def test_no_user_single_group(self, mock_members):
214214
test_users = []
215215
mock_members.return_value = test_users
216216
directory = self.directory
217-
results = directory.load_users_and_groups(groups, [])
217+
results = directory.load_users_and_groups(groups, [], False)
218218
self.assertEqual(len(list(results)), 0)
219219

220220
@mock.patch('user_sync.connector.directory_okta.OktaDirectoryConnector.iter_group_members')
@@ -224,7 +224,7 @@ def test_no_user_multiple_groups(self, mock_members):
224224
total_test_users = [[], []]
225225
mock_members.side_effect = total_test_users
226226
directory = self.directory
227-
results = directory.load_users_and_groups(groups, [])
227+
results = directory.load_users_and_groups(groups, [], False)
228228
self.assertEqual(len(list(results)), 0)
229229

230230

@@ -236,7 +236,7 @@ def test_same_user_in_multiple_groups(self, mock_members):
236236
test_user = tests.helper.create_test_user_uid()
237237
mock_members.side_effect = [[test_user], [copy.deepcopy(test_user)]]
238238
directory = self.directory
239-
result = directory.load_users_and_groups(groups, [])
239+
result = directory.load_users_and_groups(groups, [], False)
240240
result_list = list(result)
241241
self.assertEqual(result_list[0]['groups'], ['group1','group2'])
242242

tests/rules_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def mock_load_users_and_groups(groups=None, extended_attributes=None, all_users=
6969
secondary_1_umapi_name: mock_secondary_umapi_connector
7070
})
7171

72-
rule_processor = user_sync.rules.RuleProcessor({'manage_groups': True})
72+
rule_processor = user_sync.rules.RuleProcessor({'process_groups': True})
7373
rule_processor.run(directory_groups, mock_directory_connector, umapi_connectors)
7474

7575
rule_options = rule_processor.options
@@ -142,7 +142,7 @@ def mock_load_users_and_groups(groups=None, extended_attributes=None, all_users=
142142
secondary_1_umapi_name: mock_secondary_umapi_connector
143143
})
144144

145-
rule_processor = user_sync.rules.RuleProcessor({'manage_groups': True,
145+
rule_processor = user_sync.rules.RuleProcessor({'process_groups': True,
146146
'strategy': 'push',
147147
'update_user_info': True,
148148
})

0 commit comments

Comments
 (0)