X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/de3276d1b2067be4aa40b51605c2ce509ea80915..c8828ded72f562811dfe29ca20809dd5641f7a1d:/sdk/python/arvados/commands/federation_migrate.py diff --git a/sdk/python/arvados/commands/federation_migrate.py b/sdk/python/arvados/commands/federation_migrate.py index a7d9414d9d..e74d6215c7 100755 --- a/sdk/python/arvados/commands/federation_migrate.py +++ b/sdk/python/arvados/commands/federation_migrate.py @@ -3,6 +3,15 @@ # # SPDX-License-Identifier: Apache-2.0 +# +# Migration tool for merging user accounts belonging to the same user +# but on separate clusters to use a single user account managed by a +# specific cluster. +# +# If you're working on this, see +# arvados/sdk/python/tests/fed-migrate/README for information about +# the testing infrastructure. + import arvados import arvados.util import arvados.errors @@ -12,6 +21,7 @@ import argparse import hmac import urllib.parse import os +import hashlib from arvados._version import __version__ EMAIL=0 @@ -67,7 +77,7 @@ def connect_clusters(args): continue if not cur["is_admin"]: - errors.append("Not admin of %s" % host) + errors.append("User %s is not admin on %s" % (cur["uuid"], arv._rootDesc["uuidPrefix"])) continue for r in clusters: @@ -187,14 +197,17 @@ def choose_new_user(args, by_email, email, userhome, username, old_user_uuid, cl return None print("(%s) No user listed with same email to migrate %s to %s, will create new user with username '%s'" % (email, old_user_uuid, userhome, username)) if not args.dry_run: + oldhomecluster = old_user_uuid[0:5] + oldhomearv = clusters[oldhomecluster] newhomecluster = userhome[0:5] homearv = clusters[userhome] user = None try: + olduser = oldhomearv.users().get(uuid=old_user_uuid).execute() conflicts = homearv.users().list(filters=[["username", "=", username]]).execute() if conflicts["items"]: homearv.users().update(uuid=conflicts["items"][0]["uuid"], body={"user": {"username": username+"migrate"}}).execute() - user = homearv.users().create(body={"user": {"email": email, "username": username}}).execute() + user = homearv.users().create(body={"user": {"email": email, "username": username, "is_active": olduser["is_active"]}}).execute() except arvados.errors.ApiError as e: print("(%s) Could not create user: %s" % (email, str(e))) return None @@ -227,9 +240,16 @@ def activate_remote_user(args, email, homearv, migratearv, old_user_uuid, new_us print("(%s) Could not create API token for %s: %s" % (email, new_user_uuid, e)) return None + try: + olduser = migratearv.users().get(uuid=old_user_uuid).execute() + except arvados.errors.ApiError as e: + if e.resp.status != 404: + print("(%s) Could not retrieve user %s from %s, user may have already been migrated: %s" % (email, old_user_uuid, migratecluster, e)) + return None + salted = 'v2/' + newtok["uuid"] + '/' + hmac.new(newtok["api_token"].encode(), msg=migratecluster.encode(), - digestmod='sha1').hexdigest() + digestmod=hashlib.sha1).hexdigest() try: ru = urllib.parse.urlparse(migratearv._rootDesc["rootUrl"]) if not args.dry_run: @@ -240,14 +260,7 @@ def activate_remote_user(args, email, homearv, migratearv, old_user_uuid, new_us print("(%s) Error getting user info for %s from %s: %s" % (email, new_user_uuid, migratecluster, e)) return None - try: - olduser = migratearv.users().get(uuid=old_user_uuid).execute() - except arvados.errors.ApiError as e: - if e.resp.status != 404: - print("(%s) Could not retrieve user %s from %s, user may have already been migrated: %s" % (email, old_user_uuid, migratecluster, e)) - return None - - if not newuser["is_active"]: + if not newuser["is_active"] and olduser["is_active"]: print("(%s) Activating user %s on %s" % (email, new_user_uuid, migratecluster)) try: if not args.dry_run: