This repository was archived by the owner on Apr 9, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsync.py
95 lines (84 loc) · 3.45 KB
/
sync.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import click
import click_log
import logging
from requests import HTTPError
from mattermostsync import Sync, CourseNotFound, parse_course
logger = logging.getLogger('lthub.mattermost')
click_log.basic_config(logger)
@click.command()
@click_log.simple_verbosity_option(logger)
@click.option('-l', '--ldap', help='LDAP URI', envvar='LDAP_URI', default='ldaps://localhost:636', show_default=True)
@click.option('-u', '--bind', help='LDAP bind user', envvar='LDAP_BIND_USER', required=True)
@click.option(
'-p', '--password', help='LDAP bind password', envvar='LDAP_BIND_PASSWORD',
required=True, prompt=True, hide_input=True
)
@click.option('-b', '--base', help='LDAP search base', envvar='LDAP_SEARCH_BASE', show_default=True)
@click.option(
'-c', '--courses', help='Course names spec, can be specified multiple times',
envvar='COURSE_NAMES', multiple=True, required=True
)
@click.option('-r', '--url', help='Mattermost URL', envvar='MM_URL', required=True)
@click.option('-o', '--port', help='Mattermost port', envvar='MM_PORT', default=443, show_default=True)
@click.option('-t', '--token', help='Mattermost token', envvar='MM_TOKEN', required=True)
@click.option(
'-s', '--scheme', help='Mattermost scheme', envvar='MM_SCHEME',
default='https', type=click.Choice(['http', 'https']), show_default=True
)
def sync(ldap, bind, password, base, courses, url, port, token, scheme):
"""Sync class roaster from LDAP to Mattermost
"""
mm = Sync({
'url': url,
'token': token,
'port': port,
'scheme': scheme,
'debug': logger.getEffectiveLevel() <= logging.DEBUG,
'ldap_uri': ldap,
'bind_user': bind,
'bind_password': password
})
mm.driver.login()
for course in courses:
source_courses, team_name = parse_course(course)
logger.info('Syncing course {} to team {}.'.format(source_courses, team_name))
try:
course_members = []
for c in source_courses:
course_members.extend(mm.get_member_from_ldap(base, *c))
except CourseNotFound as e:
logger.warning(e)
continue
try:
team = mm.get_team_by_name(team_name)
if team:
logger.info('Team {} already exists.'.format(team_name))
else:
team = mm.create_team(team_name)
logger.info('Team {} is created.'.format(team_name))
existing_users, failed_users = mm.create_users(course_members)
# check if the users are already in the team
members = []
for i in range(1000):
m = mm.get_team_members(team['id'], {'page': i, 'per_page': 60})
if m:
members.extend(m)
continue
if len(m) < 60:
break
member_ids = [m['user_id'] for m in members]
users_to_add = []
for u in existing_users:
if u['id'] not in member_ids:
users_to_add.append(u)
# add the missing ones
if users_to_add:
mm.add_users_to_team(users_to_add, team['id'])
else:
logger.info('No new users to add.')
except HTTPError as e:
logging.error('Failed to sync team {}: {}'.format(team_name, e.args))
continue
logger.info('Finished to sync course {}.'.format(course))
if __name__ == "__main__":
sync()