2 # Copyright (C) The Arvados Authors. All rights reserved.
4 # SPDX-License-Identifier: AGPL-3.0
15 parser = argparse.ArgumentParser(description='Migrate users to federated identity')
16 parser.add_argument('--tokens', type=str)
17 group = parser.add_mutually_exclusive_group()
18 group.add_argument('--report', type=str)
19 group.add_argument('--migrate', type=str)
20 args = parser.parse_args()
24 with open(args.tokens, "rt") as f:
25 for r in csv.reader(f):
28 arv = arvados.api(host=host, token=token)
29 clusters[arv._rootDesc["uuidPrefix"]] = arv
30 cur = arv.users().current().execute()
31 if not cur["is_admin"]:
32 raise Exception("Not admin of %s" % host)
36 for c, arv in clusters.items():
37 ul = arvados.util.list_all(arv.users().list)
39 if l["uuid"].startswith(c):
42 out = csv.writer(open(args.report, "wt"))
44 out.writerow(("email", "user uuid", "primary cluster/user"))
46 users = sorted(users, key=lambda u: u["email"]+"::"+u["uuid"])
51 if u["uuid"].endswith("-anonymouspublic") or u["uuid"].endswith("-000000000000000"):
54 lastemail = u["email"]
55 if u["email"] == lastemail:
62 if a["uuid"] != homeuuid:
65 out.writerow((a["email"], a["uuid"], homeuuid[0:5]))
66 lastemail = u["email"]
73 if a["uuid"] != homeuuid:
76 out.writerow((a["email"], a["uuid"], homeuuid[0:5]))
81 with open(args.migrate, "rt") as f:
82 for r in csv.reader(f):
85 by_email.setdefault(r[0], [])
86 by_email[r[0]].append(r)
90 print("(%s) Skipping %s, no home cluster specified" % (r[0], r[1]))
91 if r[1].startswith(r[2]):
94 for b in by_email[r[0]]:
95 if b[1].startswith(r[2]):
97 if len(candidates) == 0:
98 print("(%s) No user listed to migrate %s to %s" % (r[0], r[1], r[2]))
100 if len(candidates) > 1:
101 print("(%s) Multiple users listed to migrate %s to %s, use full uuid" % (r[0], r[1], r[2]))
103 new_user_uuid = candidates[0][1]
104 print("(%s) Will migrate %s to %s" % (r[0], r[1], new_user_uuid))
105 oldcluster = r[1][0:5]
106 newhomecluster = r[2][0:5]
107 homearv = clusters[newhomecluster]
109 newtok = homearv.api_client_authorizations().create(body={"api_client_authorization": {'owner_uuid': new_user_uuid}}).execute()
110 salted = 'v2/' + newtok["uuid"] + '/' + hmac.new(newtok["api_token"].encode(), msg=oldcluster.encode(), digestmod='sha1').hexdigest()
111 arvados.api(host=arv._rootDesc["rootUrl"][8:-1], token=salted).users().current().execute()
113 # now migrate from local user to remote user.
114 arv = clusters[oldcluster]
116 grp = arv.groups().create(body={
117 "owner_uuid": new_user_uuid,
118 "name": "Migrated from %s (%s)" % (r[0], r[1]),
119 "group_class": "project"
120 }, ensure_unique_name=True).execute()
121 arv.users().merge(old_user_uuid=r[1],
122 new_user_uuid=new_user_uuid,
123 new_owner_uuid=grp["uuid"],
124 redirect_to_new_user=True).execute()
126 if __name__ == "__main__":