Guest User

Untitled

a guest
Jan 24th, 2019
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.76 KB | None | 0 0
  1. #!/usr/bin/env python2
  2.  
  3. from qumulo.rest_client import RestClient
  4.  
  5. import argparse
  6. import getpass
  7.  
  8. def parse_group_file(group_file):
  9. groups = {}
  10. gid_to_name_map = {}
  11. with open(group_file) as f:
  12. for line in f.readlines():
  13. line = line.rstrip()
  14.  
  15. chunks = line.split(':')
  16. gid = int(chunks[2])
  17. members = set()
  18. if chunks[3]:
  19. members = set(chunks[3].split(','))
  20.  
  21. # Duplicate gids indicate that we should merge groups, otherwise
  22. # create a new group
  23. if gid in gid_to_name_map:
  24. group_name = gid_to_name_map[gid]
  25. else:
  26. group_name = chunks[0]
  27. groups[group_name] = {
  28. 'gid': gid,
  29. 'members': set()
  30. }
  31.  
  32. groups[group_name]['members'].update(members)
  33. gid_to_name_map[gid] = group_name
  34.  
  35. return groups
  36.  
  37. def sync_groups(client, nis_groups, dry_run):
  38. # XXX Does not cleanly handle the case where two groups swap gid
  39. nis_groups = {
  40. 'cp_group_' + name:info
  41. for name,info in nis_groups.items()
  42. }
  43.  
  44. qumulo_groups = {
  45. u['name'].lower(): u
  46. for u in client.groups.list_groups()
  47. }
  48.  
  49. new_groups = {
  50. name:info['gid'] for name,info in nis_groups.items()
  51. if name not in qumulo_groups
  52. }
  53.  
  54. existing_groups = set([
  55. name for name in nis_groups.keys()
  56. if name in qumulo_groups
  57. ])
  58.  
  59. dead_groups = set([
  60. name for name in qumulo_groups.keys()
  61. if name not in nis_groups and
  62. name.startswith('cp_group_')
  63. ])
  64.  
  65. # XXX What happens if there are still users in the group?
  66. for name in dead_groups:
  67. if dry_run:
  68. print "Delete group " + name
  69. continue
  70.  
  71. client.groups.delete_group(qumulo_groups[name]['id'])
  72.  
  73. for name, gid in new_groups.items():
  74. if dry_run:
  75. print "Add group {} with gid {}".format(name, gid)
  76. continue
  77.  
  78. client.groups.add_group(name, gid)
  79.  
  80. for name in existing_groups:
  81. nis_gid = nis_groups[name]['gid']
  82. qumulo_gid = int(qumulo_groups[name]['gid'])
  83. if nis_gid != qumulo_gid:
  84. if dry_run:
  85. print "Change group {} gid from {} to {}".format(
  86. name, qumulo_gid, nis_gid)
  87. continue
  88.  
  89. client.groups.modify_group(
  90. qumulo_groups[name]['id'],
  91. qumulo_groups[name],
  92. nis_gid)
  93.  
  94. def parse_passwd_file(passwd_file):
  95. users = {}
  96. with open(passwd_file) as f:
  97. for line in f.readlines():
  98. chunks = line.split(':')
  99. users[chunks[0]] = int(chunks[2])
  100.  
  101. return users
  102.  
  103. def sync_users(client, nis_users, dry_run):
  104. # XXX Does not cleanly handle the case where two users swap uid
  105.  
  106. nis_users = {
  107. 'cp_user_' + name:uid
  108. for name,uid in nis_users.items()
  109. }
  110.  
  111. qumulo_users = {
  112. u['name'].lower(): u
  113. for u in client.users.list_users()
  114. }
  115.  
  116. new_users = {
  117. name:uid for name, uid in nis_users.items()
  118. if name not in qumulo_users
  119. }
  120.  
  121. existing_users = set([
  122. name for name in nis_users.keys()
  123. if name in qumulo_users
  124. ])
  125.  
  126. dead_users = set([
  127. name for name in qumulo_users.keys()
  128. if name not in nis_users and
  129. name.startswith('cp_user_')
  130. ])
  131.  
  132. for name in dead_users:
  133. if dry_run:
  134. print "Remove user " + name
  135. continue
  136.  
  137. client.users.delete_user(qumulo_users[name]['id'])
  138.  
  139. default_users_group_id = 513
  140. for name, uid in new_users.items():
  141. if dry_run:
  142. print "Add user {} with uid {}".format(name, uid)
  143. continue
  144.  
  145. client.users.add_user(
  146. name, default_users_group_id, uid)
  147.  
  148. for name in existing_users:
  149. nis_uid = nis_users[name]
  150. qumulo_uid = int(qumulo_users[name]['uid'])
  151. if nis_uid != qumulo_uid:
  152. if dry_run:
  153. print "Change user {} uid from {} to {}".format(
  154. name, qumulo_uid, nis_uid)
  155. continue
  156.  
  157. client.users.modify_user(
  158. qumulo_users[name]['id'],
  159. qumulo_users[name],
  160. default_users_group_id,
  161. nis_uid)
  162.  
  163. def sync_group_membership(client, nis_groups, dry_run):
  164. nis_groups = {
  165. 'cp_group_' + name:info
  166. for name,info in nis_groups.items()
  167. }
  168.  
  169. qumulo_groups = {
  170. u['name'].lower(): u
  171. for u in client.groups.list_groups()
  172. }
  173.  
  174. qumulo_users = {
  175. u['name'].lower(): u
  176. for u in client.users.list_users()
  177. }
  178.  
  179. for group_name, info in qumulo_groups.items():
  180. if not group_name.startswith('cp_group_'):
  181. continue
  182.  
  183. qumulo_members = set([
  184. member['name'] for member in
  185. client.groups.group_get_members(info['id'])
  186. ])
  187.  
  188. # Check if the group has been deleted
  189. if group_name not in nis_groups:
  190. continue
  191.  
  192. nis_members = [
  193. 'cp_user_' + name
  194. for name in nis_groups[group_name]['members']
  195. ]
  196.  
  197. new_members = [
  198. name for name in nis_members
  199. if name not in qumulo_members
  200. ]
  201.  
  202. dead_members = [
  203. name for name in qumulo_members
  204. if name not in nis_members
  205. ]
  206.  
  207. for name in new_members:
  208. if dry_run:
  209. print 'Add user {} to group {}'.format(
  210. name, group_name)
  211. continue
  212.  
  213. qumulo_user = qumulo_users[name]
  214. client.groups.group_add_member(
  215. info['id'], qumulo_user['id'])
  216.  
  217. for name in dead_members:
  218. if dry_run:
  219. print 'Remove user {} from group {}'.format(
  220. name, group_name)
  221. continue
  222.  
  223. qumulo_user = qumulo_users[name]
  224. client.groups.group_remove_member(
  225. info['id'], qumulo_user['id'])
  226.  
  227. def main():
  228. parser = argparse.ArgumentParser()
  229. parser.add_argument('--host', required=True)
  230. parser.add_argument('--port', default=8000)
  231. parser.add_argument('--passwd-file', required=True)
  232. parser.add_argument('--group-file', required=True)
  233. parser.add_argument('--dry-run', action='store_true')
  234.  
  235. args = parser.parse_args()
  236.  
  237. client = RestClient(
  238. args.host, args.port, reuse_connection=True)
  239.  
  240. admin_password = getpass.getpass()
  241. client.login('admin', admin_password)
  242.  
  243. groups = parse_group_file(args.group_file)
  244. sync_groups(client, groups, args.dry_run)
  245.  
  246. users = parse_passwd_file(args.passwd_file)
  247. sync_users(client, users, args.dry_run)
  248.  
  249. sync_group_membership(client, groups, args.dry_run)
  250.  
  251. if __name__ == '__main__':
  252. main()
Add Comment
Please, Sign In to add comment