Skip to content

Commit e347850

Browse files
dnicholdnichol
authored andcommitted
Scripts to bulk edit user's email addresses and user group names from CSV
1 parent 693c633 commit e347850

File tree

2 files changed

+208
-0
lines changed

2 files changed

+208
-0
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
'''
2+
Created on Jan 27, 2023
3+
@author: dnichol
4+
Bulk update user group names from CSV. CSV file requires two columns, titled 'Existing' and 'New'. This script is case sensitive.
5+
'''
6+
7+
import csv
8+
import logging
9+
import argparse
10+
import sys
11+
import json
12+
import traceback
13+
from requests import HTTPError, RequestException
14+
15+
from blackduck import Client
16+
17+
def log_config():
18+
# TODO: debug option in .restconfig file to be reflected
19+
logging.basicConfig(format='%(asctime)s:%(levelname)s:%(module)s: %(message)s', stream=sys.stderr, level=logging.DEBUG)
20+
logging.getLogger("requests").setLevel(logging.WARNING)
21+
logging.getLogger("urllib3").setLevel(logging.WARNING)
22+
logging.getLogger("blackduck").setLevel(logging.WARNING)
23+
24+
def parse_parameter():
25+
parser = argparse.ArgumentParser("Bulk update user groups from CSV file - modifies the name of the user groups given the existing name and new name")
26+
parser.add_argument("CSV", help="Location of the CSV file")
27+
# "CSV File requires two columns titled 'Existing' and 'New'",
28+
return parser.parse_args()
29+
30+
def get_user_group_by_name(hub_client, name):
31+
params = {
32+
'q': [f"name:{name}"]
33+
}
34+
for user_group in hub_client.get_items("/api/usergroups", params=params):
35+
if user_group['name'] == name:
36+
user_url = hub_client.list_resources(user_group)['href']
37+
print(f"Found user group: {name}")
38+
return user_group
39+
40+
41+
def read_csv(hub_client, csv_path):
42+
updated = 0
43+
failed = 0
44+
not_found = 0
45+
with open(csv_path, newline='') as csvfile:
46+
reader = csv.DictReader(csvfile)
47+
for row in reader:
48+
existing_name = (row['Existing'])
49+
new_name = (row['New'])
50+
try:
51+
user = get_user_group_by_name(hub_client, existing_name)
52+
if user:
53+
update_user_group(hub_client, existing_name, new_name, user)
54+
updated += 1
55+
else:
56+
logging.info(f"User group {existing_name} was not found")
57+
not_found += 1
58+
except RequestException as err:
59+
logging.error(f"Failed to update user group {existing_name}. Reason is " + str(err))
60+
failed += 1
61+
except Exception as err:
62+
raise err
63+
64+
logging.info(f"------------------------------")
65+
logging.info(f"Execution complete.")
66+
logging.info(f"{updated} user groups updated")
67+
logging.info(f"{not_found} user groups were not found")
68+
logging.info(f"{failed} user groups failed to update")
69+
70+
def update_user_group(hub_client, existing_name, new_name, user_group):
71+
user_group_url = hub_client.list_resources(user_group)['href']
72+
73+
# Update the name.
74+
user_group['name'] = new_name
75+
76+
logging.info(f"Updating user group {existing_name} to {user_group['name']} for user group {user_group_url}s")
77+
hub_client.session.put(user_group_url, json=user_group)
78+
79+
80+
def main():
81+
log_config()
82+
args = parse_parameter()
83+
try:
84+
with open('.restconfig.json','r') as f:
85+
config = json.load(f)
86+
hub_client = Client(token=config['api_token'],
87+
base_url=config['baseurl'],
88+
verify=not config['insecure'],
89+
timeout=15,
90+
retries=3)
91+
92+
read_csv(hub_client, args.CSV)
93+
except HTTPError as err:
94+
hub_client.http_error_handler(err)
95+
except Exception as err:
96+
logging.error(f"Failed to perform the task. See the stack trace")
97+
traceback.print_exc()
98+
99+
if __name__ == '__main__':
100+
sys.exit(main())
101+

examples/update_users_from_csv.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
'''
2+
Created on Jan 27, 2023
3+
@author: dnichol
4+
Bulk update users email addresses from CSV. CSV file requires two columns, titled 'Existing' and 'New'. This script is case sensitive.
5+
'''
6+
7+
import csv
8+
import logging
9+
import argparse
10+
import sys
11+
import json
12+
import traceback
13+
from requests import HTTPError, RequestException
14+
15+
from blackduck import Client
16+
17+
def log_config():
18+
# TODO: debug option in .restconfig file to be reflected
19+
logging.basicConfig(format='%(asctime)s:%(levelname)s:%(module)s: %(message)s', stream=sys.stderr, level=logging.DEBUG)
20+
logging.getLogger("requests").setLevel(logging.WARNING)
21+
logging.getLogger("urllib3").setLevel(logging.WARNING)
22+
logging.getLogger("blackduck").setLevel(logging.WARNING)
23+
24+
def parse_parameter():
25+
parser = argparse.ArgumentParser("Bulk update users from CSV file - modifies the email addresses of the users given the existing email and new email address")
26+
parser.add_argument("CSV", help="Location of the CSV file")
27+
# "CSV File requires two columns titled 'Existing' and 'New'",
28+
return parser.parse_args()
29+
30+
def get_user_by_email(hub_client, email):
31+
params = {
32+
'q': [f"name:{email}"]
33+
}
34+
for user in hub_client.get_items("/api/users", params=params):
35+
if user['email'] == email:
36+
user_url = hub_client.list_resources(user)['href']
37+
print(f"Found user: {email}")
38+
return user
39+
40+
41+
def read_csv(hub_client, csv_path):
42+
updated = 0
43+
failed = 0
44+
not_found = 0
45+
with open(csv_path, newline='') as csvfile:
46+
reader = csv.DictReader(csvfile)
47+
for row in reader:
48+
existing_email = (row['Existing'])
49+
new_email = (row['New'])
50+
try:
51+
user = get_user_by_email(hub_client, existing_email)
52+
if user:
53+
update_user(hub_client, existing_email, new_email, user)
54+
updated += 1
55+
else:
56+
logging.info(f"User {existing_email} was not found")
57+
not_found += 1
58+
except RequestException as err:
59+
logging.error(f"Failed to update user {existing_email}. Reason is " + str(err))
60+
failed += 1
61+
except Exception as err:
62+
raise err
63+
64+
logging.info(f"------------------------------")
65+
logging.info(f"Execution complete.")
66+
logging.info(f"{updated} users updated")
67+
logging.info(f"{not_found} users were not found")
68+
logging.info(f"{failed} users failed to update")
69+
70+
def update_user(hub_client, existing_email, new_email, user):
71+
user_url = hub_client.list_resources(user)['href']
72+
73+
# Update the email address.
74+
user['email'] = new_email
75+
76+
# Not just update the email address. If the email is also used as userName and externalUserName then update them too.
77+
if user['userName'] == existing_email:
78+
user['userName'] = new_email
79+
if user.get('externalUserName') and user['externalUserName'] == existing_email:
80+
user['externalUserName'] = new_email
81+
82+
logging.info(f"Updating user {existing_email} to {user['email']} for user {user_url}s")
83+
hub_client.session.put(user_url, json=user)
84+
85+
86+
def main():
87+
log_config()
88+
args = parse_parameter()
89+
try:
90+
with open('.restconfig.json','r') as f:
91+
config = json.load(f)
92+
hub_client = Client(token=config['api_token'],
93+
base_url=config['baseurl'],
94+
verify=not config['insecure'],
95+
timeout=15,
96+
retries=3)
97+
98+
read_csv(hub_client, args.CSV)
99+
except HTTPError as err:
100+
hub_client.http_error_handler(err)
101+
except Exception as err:
102+
logging.error(f"Failed to perform the task. See the stack trace")
103+
traceback.print_exc()
104+
105+
if __name__ == '__main__':
106+
sys.exit(main())
107+

0 commit comments

Comments
 (0)