[Solved] Help! LDAP Migration w/ New Usernames


#1

We are moving to a new domain for authentication and I am not sure about how to go about migrating.

  • Email addresses are staying the name
  • All usernames are changing to a new format
  • LDAP is changing

We are currently running version 9.0.5 of Gitlab CE, though we will update to latest before migrating. My current guess on how the process should go without messing up a bunch of history, permissions, etc. is:

  1. Change usernames from current format to new format (we have a list of before/after)
  2. Change system config to new LDAP settings
  3. Is there some individual user settings that need to be changed too for LDAP?
  4. Restart?
  5. Hope and Pray?

Edit: Solution
I ended up writing ruby functions that I could call on the ‘gitlab-rails console production’

  1. First, I had to update the email addresses to the ones that are in the new LDAP system (they set up a proxy to our old email addresses, but mail attribute is set to new one)
  2. To get around the reconfirmation issue for email change, I called ‘user.skip_reconfirmation!’ before I called ‘user.save!’
  3. Next I changed the system config with the new LDAP settings
  4. Reconfigured and restarted Gitlab
  5. Then I ran my second ruby function from the console to update all of the usernames to the new format

After this, everyone was able to login with their new usernames and their internal identities updated properly.


How to convert local gitlab user (email) to LDAP user?
#2

@alison-gravley Please show your script for me, i want change ldap too.


#3
  1. Login to your gitlab server (the linux box, not the web interface)
  2. I created a script and put my .rb file in /opt/gitlab/embedded/service/gitlab-rails/lib/
  3. I used a tab delimited list of users with their names, gitlab id numbers, old/new email, old/new username, etc.
  4. It is important that any input files are somewhere that gitlab won’t complain about permissions. I ended up putting mine in /tmp
  5. Open up the gitlab rails console by typing in gitlab-rails console production
  6. From here you can test your commands directly before actually calling functions from your script.
  7. To call a function in your rb

Some command examples on how to search for and update users:

  1. Find the user by whatever method is easiest. Here are a few options
    a. user = User.find_by(email: 'email@email.com')
    b. user = User.find_by(username: 'myusername')
    c. user = User.where(id: 2).first
  2. To update a username:
    a. user.username = 'newuser'
    b. user.save!
  3. To update an email:
    a. user.email = 'newemail'
    b. user.skip_reconfirmation!
    c. user.save!
  4. To forcibly unblock a user:
    a. user.state = 'active'
    b. user.save!

The steps I took in my migration:

  1. Update email addresses
    a. update_emails('/tmp/all_gitlab_users.txt')
  2. Change gitlab.rb to new ldap configuration
  3. gitlab-ctl reconfigure
  4. gitlab-ctl restart
  5. Double check ldap config with gitlab-rake gitlab:ldap:check
  6. If you used a different provider name in your new ldap config, run the rename provider command
    a. gitlab-rake gitlab:ldap:rename_provider[ldapmain,ldapnewmain]
  7. gitlab-ctl restart
  8. Update usernames
    a. update_usernames('/tmp/all_gitlab_users.txt')
  9. Have users login with new credential through the web interface. Should be ok now. If they have a “1” in their username that means email addresses didn’t match in the new ldap server.

Here is the contents of my migration.rb file:

#!/usr/bin/env ruby

def update_emails(input_file)
  file=input_file

  f = File.open(file, "r")
  puts "Opening file #{file} for email conversion..."

  #<user_id> <current_username> <new_username> <new_email> <current_email> <real_name>
  f.each_line { |line|
    #Split the string by tabs
    tokens = line.split("\t")
    if tokens.size == 6
      user_id = tokens[0]
      curr_user = tokens[1]
      upd_user = tokens[2]
      upd_email = tokens[3]
      curr_email = tokens[4]
      real_name = tokens[5]

      user = User.where(id: user_id).first
      if user
        puts "Updating Email For - ID: #{user_id}, CurrentUsername: #{curr_user}, Current Email: #{user.email}, New Email #{upd_email}"
        user.email = upd_email
        user.skip_reconfirmation!
        user.save!
      else
       puts "Unable to find user with id = #{user_id}. CurrentUsername: #{curr_user}, Real Name: #{real_name}"
      end
    else
      puts "Error! Line does not have 6 tokens. Has #{tokens.size}: #{line}"
    end
  }
  f.close
  puts "Finished Processing Email Updates"
end

def update_usernames(input_file)
  file=input_file

  f = File.open(file, "r")
  puts "Opening file #{file} for username conversion..."

  #<user_id> <current_username> <new_username> <new_email> <current_email> <real_name>
  f.each_line { |line|
    #Split the string by tabs
    tokens = line.split("\t")
    if tokens.size == 6
      user_id = tokens[0]
      curr_user = tokens[1]
      upd_user = tokens[2]
      upd_email = tokens[3]
      curr_email = tokens[4]
      real_name = tokens[5]

      user = User.where(id: user_id).first
      if user
        puts "Updating Username For - ID: #{user_id}, CurrentUsername: #{curr_user}, Current Username: #{user.username}, New Username #{upd_user}"
        user.username = upd_user
        user.save!
      else
       puts "Unable to find user with id = #{user_id}. CurrentUsername: #{curr_user}, Real Name: #{real_name}"
      end
    else
      puts "Error! Line does not have 6 tokens. Has #{tokens.size}: #{line}"
    end
  }
  f.close
  puts "Finished Processing Username Updates"
end