How-to: change the primary domain in the G Suite for the entire company and retain all the data
- Tutorial
There was a need to change the main domain of the company in G Suite from .ru to .com with saving all data, calendars, aliases and access to third-party resources. There is not much information about moving to the Internet, or rather, apart from Google’s help, nothing was found at all, which was the reason for the creation of this how-to. It will be useful if someone decides to repeat this.
The fact is that initially the company used the pixonic.ru domain. Then the nickname pixonic.com was added, but everywhere by default there was mail in the .ru zone. And since many company employees are in correspondence with foreign colleagues and clients, there was a desire to use the international format. To do this, they had to go into the account settings, independently change the main mailing address and bring the signature in accordance with the corporate template. Not everyone did it (or did, but after a time) and one can imagine what mess and confusion was happening in the message branches. For external partners, this looked even less presentable due to different signatures.
In general, the time came when it was decided - all correspondence should be conducted using pixonic.com mail. The task fell on us - system administrators.
At the end of the article there is a link to the entire script, so only its pieces will be in the text.
We use Google for business, so the mail is located on the same service. So what was there:
- Domain pixonic.ru.
- Aliases are pixonic.com and pixonic.org.
- ~ 200 accounts and ~ 80 distribution groups.
- A bunch of aliases for some accounts.
- Calendars, including common for the company.
- Connected Google Analytics.
- Dozens of terabytes of important information on Google Drive.
- Third-party services Jira, Slack, and others in which authorization occurred using a Google account.
What was planned:
- Make pixonic.com the main domain, and pixonic.ru and pixonic.org are its aliases.
- Moving all accounts to pixonic.com with all correspondence and information stored on Google Drive.
- Relocation of postal groups with preservation of the composition and rights of its participants.
- Save all user aliases.
- Save access to all shared files in Google Drive for accounts.
- Saving calendars so that information about scheduled meetings and events is not lost.
- Saving accesses in Jira and Slack.
- To the maximum to avoid the loss of mail.
Of course, the first thing they wrote to tech support was to change our main domain. They got the answer - they can’t do this and, in general, they advised that they never risk it.
Okay. Reconfiguring each user’s account manually is a so-so prospect. Moreover, a similar procedure would have to be done for each new employee separately. You can still try to do it through the API, but again - this will not solve all the problems, because many use third-party email clients with old settings. And the problem with new employees will not go anywhere.
There are five points in the help certificate for moving from Google itself:
- Add an additional domain and configure MX records.
- Make the new domain primary.
- Rename users according to the new primary domain.
- Rename the groups according to the new primary domain.
- Delete the old primary domain (optional).
It doesn’t look complicated, you have to try.
What exactly will remain and what may be lost as a result of such actions was not indicated. Therefore, we made a test environment, bought another G Suit and added test domains to it.
Then they identified the requirements for moving: the preservation of information, rights and access of users. Those. the only problem the end user had to face was the need to re-enter their new account on all devices.
And they started the tests.
Testing possible scenarios and testing took us almost a month. The test results were very encouraging, so we decided to repeat everything on a working environment.
Action algorithm
All that could be done with no hands was done by a Python 3.6 script. From third-party modules, we need google-api-python-client, oauth2client, httplib2, apiclient and pyopenssl. Install without pip problems.
To use the Google API, you need to create a service account in the developer console . To do this, create a project (or use the existing one), select “Credentials → Create credentials → Service account key”.
We select “New service account”, name it, assign the role “Owner”, select the key P12 (it’s not very important about the key, but during the tests I managed to log in with JSON only with explicit permission from the specific user on whose behalf operations, which in this case is not suitable).
Authorize the service account in the administrator’s console under “Security → Advanced Settings → Control API Client Access”.
The API can only work in the area in which it is authorized (a description of all areas can be found here ). I used the following:
- Email (Read / Write / Send) mail.google.com
- www.googleapis.com/auth/activity
- View and manage the provisioning of groups on your domain www.googleapis.com/auth/admin.directory.group
- View and manage the provisioning of users on your domain www.googleapis.com/auth/admin.directory.user
- www.googleapis.com/auth/drive.metadata.readonly
- www.googleapis.com/auth/gmail.settings.basic
- www.googleapis.com/auth/gmail.settings.sharing
After the API is verified, you can proceed to the migration work itself.
The basis of the entire script is obtaining rights and delegating them to a user depending on the required actions. Those. if you need to change the signature of someone in the mail, then delegation must be made to the same account; if you get a list of users - then to the administrator account, etc.
So it looks with me:
def get_credentials(email):
# Авторизация и делегирование прав на e-mail
credentials = ServiceAccountCredentials.from_p12_keyfile(
SERVICE_ACCOUNT_EMAIL,
SERVICE_ACCOUNT_PKCS12_FILE_PATH,
'notasecret',
scopes=['https://www.googleapis.com/auth/admin.directory.user',
'https://www.googleapis.com/auth/gmail.settings.sharing',
'https://www.googleapis.com/auth/gmail.settings.basic', 'https://mail.google.com/',
'https://www.googleapis.com/auth/activity',
'https://www.googleapis.com/auth/drive.metadata.readonly',
'https://www.googleapis.com/auth/admin.directory.group'])
delegate_credentials = credentials.create_delegated(email)
return delegate_credentials.authorize(httplib2.Http())
In fact, we call this function before each action, then select the application in which we need to perform manipulations and launch the API. Execution The API returns either the result of the execution or the data that was requested.
http = get_credentials(adminEmail)
service = build('admin', 'directory_v1', http=http)
data = service.users().aliases().list(userKey=usermail).execute()
print(data)
We begin the work by creating a backup of everything that we may need, namely: information about users, groups, group memberships, user aliases and group aliases.
Everything is simple here: we request the Old, write to a file, since Google provides all the information in JSON format and it’s convenient to work with it.
def backUpInfo(filename=''):
path = os.path.expanduser('~/Documents/backup/')
prefix = path+'backup'
if not (filename == ''):
prefix = path + filename
#backupUsers
with open(prefix + 'Users.json', 'w') as file:
userInfo = getAllInfoUsers()
file.write(json.dumps(userInfo, indent=4))
print(prefix + 'Users.json done')
#backupGroups
with open(prefix + 'Groups.json', 'w') as file:
groupInfo = getAllInfoGroups()
file.write(json.dumps(groupInfo, indent=4))
print(prefix + 'Groups.json done')
#backupUsersInGroups
with open(prefix + 'UsersInGroups.json', 'w') as file:
groupInfo = getAllUsersInGroups()
file.write(json.dumps(groupInfo, indent=4))
print(prefix + 'UsersInGroups.json done')
#backupUsersAliases
with open(prefix + 'UsersAliases.json', 'w') as file:
info = getUsersAliases()
file.write(json.dumps(info, indent=4))
print(prefix + 'UsersAliases.json done')
#backupGroupsAliases
with open(prefix + 'GroupsAliases.json', 'w') as file:
info = getGroupAliases()
file.write(json.dumps(info, indent=4))
print(prefix + 'GroupsAliases.json done')
The next step is to remove the com alias and add it as a domain. These actions are performed in the administration console → Domains → Add / Remove Domains.
When adding a domain, you need to specify MX records and the service needs some time to check them (in our case, it took a couple of minutes). In principle, the end of the test can not wait and continue to work.
After adding a domain, it will be possible to make it the main one, which we are doing (this is not possible in the trial version of G suit, it appears only in the paid version and not immediately after payment, but only after the trial period expires, which is strange).
Then we transfer users and groups to the new domain. The algorithm is as follows:
- we delegate rights to the administrator account;
- unload the entire list of users;
- we go through each user, except for the administrator account under which we work;
- and change the primaryEmail field through the API function users (). update ().
Those. transferring a user through the API consists in changing the domain in the main mailing address from .ru to .com. It looks like this:
def moveUsers(domain):
# Получаем список всех пользователей
users = getUsers()
# Переименовываем всех пользователей, кроме adminEmail
for a in users:
if adminEmail in a[0]: continue
try:
renameUser(a[0], domain)
print('Done: ' + a[0])
except Exception as e:
print(sys.exc_info()[0], ":", e)
print('Failed: ' + a[0])
print("Users done!!!")
The users (). Update () function is very useful because it allows you to change any information in the user profile. The user login and variable parameters in JSON format are passed to her in the parameters.
def renameUser(email, domain):
patch = {'primaryEmail': changeMailDomain(email=email, domain=domain)}
http = get_credentials(adminEmail)
service = build('admin', 'directory_v1', http=http)
service.users().update(userKey=email, body=patch).execute()
In the same way, you can add information to your profile, for example: Skype account, additional position and anything else to your taste.
We carry out a similar operation for groups.
Transfer your account to a new domain. After that, you need to log into your new account and authorize the service account again. It is not required to change anything in it, just take its name from the “Authorized API Clients” column, and the list of necessary areas from the second column.
There shouldn't be anyone in our old domain right now. Therefore, go to the list of domains in the administrator console and delete it. And then we add it to the place, but already as an alias (if you need the old domain at all).
There is the final touch. After we removed the alias “com” at the beginning, all user and group aliases were deleted, so we need to restore them from the backup that we did at the very beginning. In this case, it makes sense to change the domain to our new one in all aliases, as aliases will appear automatically on all secondary domains. To do this, download the information from the backup, go through each user and restore all the aliases if they are available using users (). Aliases (). Insert (userKey = email, body = body).
A similar operation is performed for groups.
Well, that’s it.
Link to Github.
PS Some changes are not immediately visible. For example, after deleting the old domain and adding it as an alias, if you go to someone’s account in the admin panel, its aliases will be visible there, which actually are no longer there. In any case, they will have to be restored.
What is the result?
We moved with a minimum of losses. Work from the moment of creating the backup copy until the restoration of the aliases took ~ 20 minutes.
Accesses are not lost, the composition of the mail groups has not changed. No one complained to us about any problem with the account, they say, I can’t log into the account or read any file. Common calendars remained intact, scheduled events did not disappear.
With third-party services, not everything is so joyful, although acceptable. Authorization in them did not fly away, but whoever registered to the old mail should go under it, so you can’t select the login via Google+. This did not affect us much, because all users were warned about this before and after the completion of work. In the case of Slack, the problem can also be solved through the API by changing the addresses of users. In cloud Jira, alas, this will not work, but if you use a local server, then the problem is solved.
As a bonus, we got a good tool for creating users with ready-made signatures made according to a corporate template. And if necessary, the signature is easy to update without user intervention. In addition, using the API it is convenient to update information in the employee profile or, on the contrary, to receive it.