User mapping while migrating Confluence spaces (export / import) - how?

Daniel November 13, 2019

Hi community, 

I hope you can help me.

I need to migrate several Confluence Spaces from Confluence Server 6.10.1 to another Confluence Server instance (version unknown yet, but not older than 6.10.1).

The usernames (and certainly also the user IDs) will be different between source and target side.

What is the best way to migrate the spaces and map the users correctly? We thought about soing search-and-replace in the exported XML before importing, but there are users referenced in a mixed way sometimes with their email addresses (which are the usernames on source instance) and sime kind of ID or hash.

<object class="ConfluenceUserImpl" package="com.atlassian.confluence.user">
<id name="key"><![CDATA[ff80818169286c7e016a11f1d2f5000a]]></id>
<property name="name"><![CDATA[john.doe@example.com]]></property>
<property name="lowerName"><![CDATA[john.doe@example.com]]></property>
</object>

Do I have to evaluate these objects like the above one, in order to find out the mapping between username and key, so I can replace all the keys accordingly in objects like the below one, where only keys are used?


<object class="User2ContentRelationEntity" package="com.atlassian.confluence.internal.relations.dao">
<id name="id">1345102</id>
<property name="targetContent" class="Page" package="com.atlassian.confluence.pages"><id name="id">984062</id>
</property>
<property name="sourceContent" class="ConfluenceUserImpl" package="com.atlassian.confluence.user"><id name="key"><![CDATA[ff80818164dabce30164eebfbe150004]]></id>
</property>
<property name="targetType" enum-class="RelatableEntityTypeEnum" package="com.atlassian.confluence.internal.relations">PAGE</property>
<property name="relationName"><![CDATA[collaborator]]></property>
<property name="creationDate">2018-09-24 10:39:18.000</property>
<property name="lastModificationDate">2018-09-24 10:39:18.000</property>
<property name="creator" class="ConfluenceUserImpl" package="com.atlassian.confluence.user"><id name="key"><![CDATA[ff80818164dabce30164eebfbe150004]]></id>
</property>
<property name="lastModifier" class="ConfluenceUserImpl" package="com.atlassian.confluence.user"><id name="key"><![CDATA[ff80818164dabce30164eebfbe150004]]></id>
</property>
</object>

If that's the case, is there any tool that can help with this task?

Thank you!

Daniel

3 answers

1 vote
Erik Anderson September 2, 2022

Fast-forward a year and a bit.  :)

Scenario:

  • Server A and Server B both run Confluence, but have different user accounts.  Users at Subsidiary A running Server A have accounts at Subsidiary B running Server B, but the credentials are different: Server A username "USERNAME@www.example.com" is implemented on Server B as "prefix_USERNAME".

Steps:

  • Export space ABC from Server A to XML.
  • Import XML file into Server B.
  • Subsidiary A user logs into Server B using Server B credentials.  Edits a page that they had previously edited on Server A.
  • Export space ABC from Server B to XML.
  • Examine the XML content.

Poking around in the export file, you should be able to find XML structures like the following.  These are, unfortunately, scattered throughout the file, so you might have to do some digging.  Also, they probably won't be paired up nicely like this, so you'll have to use Search features.

<object class="ConfluenceUserImpl" package="com.atlassian.confluence.user">
<id name="key">8af2e18d78f3a4630179448450f0002c</id>
<property name="name">USERNAME@www.example.com</property>
<property name="lowerName">USERNAME@www.example.com</property>
<property name="email"/>
</object>
<object class="ConfluenceUserImpl" package="com.atlassian.confluence.user">
<id name="key">8af281d954c032310149f548eb6c000e</id>
<property name="name">prefix_USERNAME</property>
<property name="lowerName">prefix_USERNAME</property>
<property name="email">USERNAME@www.example.com</property>
</object>

Once you can find all of the ConfluenceUserImpl objects and correlate them based on USERNAME (or whatever key your company might have implemented), you can then go through and replace the GUID value for the old one (in the example above, the one for USERNAME@www.example.com) with the GUID for the new one (the one for prefix_USERNAME) in the XML file, and then import that back into Server B.

Alternatively, it looks like it's possible for Confluence admins to fix this with moderate difficulty by tweaking the database, as described in How to change the creator of a page | Confluence | Atlassian Documentation, running queries like the following:

update content set creator = (select user_key from user_mapping where lower_username = 'prefix_USERNAME')
where creator = (select user_key from user_mapping where lower_username = 'USERNAME@www.example.com');

I hope this helps someone work through this, until such time as Atlassian gives us a better way forward.

1 vote
Michael Mohr July 28, 2022

Had you finally made progress on your space migration and mapping of users? Because we are now facing the same issue with a company the we purchased and for what we now want to consolidate their own Confluence spaces in our central confluence installation. But even that physically the users stay the same from the purchased company, their accounts are different in bot systems as the purchased company had attached their Confluence to their AD.

0 votes
Diego
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
November 14, 2019

Hello there, @Daniel ! Migrating users can be a tough procedure to complete, but it can be done.

First, there are a few things we need to clarify before. Here we go:

  • Space XML exports do not contain users, at all
  • The full site export to XML does contain the users
  • Restoring a full site XML will overwrite the entire destination instance
  • You could recreate all the users from the original instance into your destination via SQL. We strongly advise against this.

Crowd does have enough power to import and export users at will. Here is our documentation on this for Crowd:

 

Confluence does not have this functionality (export user data as CSV). But we do have a database workaround that might help:

You could also make use of a third-party addon that does export users to CSV. Here, take a look, Daniel:

 

However, if your aim is to simply migrate content (pages, spaces, and users) from one instance into another, you can use the full site XML export. This, however, will erase all content that already exists in the destination Confluence.

Here is how we do it:

  1. Go to the original instance
  2. Click the Cog icon at the top right corner
  3. Select General Configuration
  4. Search for Backup & Restore at the left side menu bar
  5. Under Export this site click the Export button   BackupRestoreUsers.jpg
  6. Now, go to your Home Diretory
  7. Go into the backups folder
  8. Grab the XML file from there
  9. Go to the destination Confluence
  10. Click the Cog icon at the top right corner
  11. Select General Configuration
  12. Search for Backup & Restore at the left side menu bar
  13. Now we can select between uploading a file or restoring the XML from the Home Directory
  14. Select to restore from home directory if your XML exceeds 1GB
  15. Import the XML

To find your home folder, you can do the following:

  1. Click the Cog Icon at the top right corner
  2. Select General Configuration
  3. Search for System Information in the left side menu bar
  4. Search for Confluence Home
  5. You will see the path to your home folder there

 

The process above will restore all the content from the original instance into the destination instance. However, everything in the destination will be erased and replaced with the XML data.

Here is the warning from within Confluence:

Anotação 2019-11-14 164503.jpg

 

Also, here is our documentation on content import and export for Confluence:

 

I hope this shine some light at your situation, Daniel. Looking forward to your reply!

Daniel November 15, 2019

Thank you @Diego for the eloquent answer.

Users will be migrated on another level (from Crowd to an Active Directory), but user names will be modified in that step (currently we have email addresses as user names, they will be changed to cryptic strings). Maybe we even need to rename the users before migrating them into the new instance. Let's use this as the most probably scenario:

My questions only concerns the mapping of user names inside Confluence content (and also Jira content in another step). 

Only users mentioned in the Confluence backup XML (or Jira backup XML) need to be mapped in this step. Not all user names in our system. So it doesn't matter that not all user data is contained in the backup XMLs of Confluence and Jira.

Okay, let's assume, we have current user john.doe@example.com, who will be named "ABC123" in the target environment.

Do you think, we'll be safe going the following route?:

1. Rename the user in current Crowd from  john.doe@example.com to ABC123

2. Sync all directories

3. Backup Confluence space.

4. Migrate users to target environment (Crowd > AD)

5. Sync all directories on target environment

6. Import Confluence space XML on target environment

Will the users be mapped correctly then? On the target environment, there already exist other users, so user keys (those which are internally used) will not be the same on source and target environment. So mathing can only be done via user name. Will this work?

 

In case it won't work as described above:

Is it correct, that in the Confluence XML I need to parse all the objects like this:

<object class="ConfluenceUserImpl" package="com.atlassian.confluence.user">
<id name="key"><![CDATA[ff80818169286c7e016a11f1d2f5000a]]></id>
<property name="name"><![CDATA[ABC123]]></property>
<property name="lowerName"><![CDATA[ABC123]]></property>
</object>

...to create a table with users name / key mappings like this:

User name | source env. user key

ABC123 | ff80818169286c7e016a11f1d2f5000a 

Then, on target side, after XML import, we generate a similar table that will have different keys for each user name and then we merge the tables like this:

User name | source env. user key | target env. user key

ABC123 | ff80818169286c7e016a11f1d2f5000a | DIFFERENTKEYhisadhoiasudh982

And then, we can do a search-and-replace in the Space XML, replacing the old key with the new one, then re-import the XML.

 

And: Is it the same with Jira?

Thank you,

Daniel

Like Erik Anderson likes this
Jeramy S February 11, 2020

@Daniel - Were you able to figure out how to map the users? If you did, did you use a special program for the find and replace or did you script something internally?

Like Erik Anderson likes this
Erik Anderson May 12, 2021

I have the same problem.

We have two Confluence servers (for various reasons I won't go into).

Users on Server A also have accounts on Server B.

We must sometimes migrate content (not the users, the content -- the Confluence spaces) from Server A to Server B.

  • If content on Server A has page-level restrictions so that only certain users can edit, we can migrate that space to Server B -- but then the restricted page isn't editable by anyone, since the restrictions are based on users who are not defined on Server B.  Someone must manually remove the page-level restrictions, page-by-page, within Confluence on Server B.  This is tedious, time-consuming, and error-prone.

What we need is one of two things.

  1. Ideally, Atlassian would implement a means of mapping users from Server A to Server B.  This might be a dialog that pops up on import, prompting us to correlate each Server A user mentioned in the XML import with a user on Server B.
  2. Alternatively, and more simply, Atlassian would document the XML export format to explain where page-level restrictions are defined, how users are identified in the XML (some sort of GUID, presumably?), and some way of correlating those user identifiers with the user names in the UI, so that we could create our own script to alter the XML to suit our purposes.
    • I have combed through the XML export, and I cannot find either how page-level restrictions are defined, nor how users are identified.  Googling hasn't helped either.

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events