Migrate existing data
Now that the migrations have run, we can upgrade the rest of the app. Let's start my also migrating any existing data.
Add the following code to 'internal/common/const.go':
package common
const (
// Resource Types
Account_RT = "Account"
Project_RT = "Project"
Sprint_RT = "Sprint"
Story_RT = "Story"
// Account Actions
CreateProject_A = "CreateProject"
AddUser_A = "AddUser"
// Project Actions
ReadProject_A = "ReadProject"
DeleteProject_A = "DeleteProject"
CreateSprint_A = "CreateSprint"
// Sprint Actions
ReadSprint_A = "ReadSprint"
StartSprint_A = "StartSprint"
EndSprint_A = "EndSprint"
CreateStory_A = "CreateStory"
// Story Actions
ReadStory_A = "ReadStory"
EstimateStory_A = "EstimateStory"
ChangeStoryStatus_A = "ChangeStoryStatus"
ChangeStoryAssignee_A = "ChangeStoryAssignee"
// Policies
CanManageAccount_P = "CanManageAccount"
// Roles
AccountAdministrator_R = "AccountAdministrator"
)
This simply defines some constants we'll use later in the code.
Next, add the following code to 'cmd/api/api.go' (just before starting the webserver):
// migrate existing data to cerberus
accounts, err := accountRepo.FindAll()
if err != nil {
log.Fatal(err)
}
for _, account := range accounts {
// admin user
adminUser, err := userRepo.FindOneByEmail("admin")
if err != nil {
log.Fatal(err)
}
// Get token
tokenPair, err := cerberusClient.GetUserToken(account.Id, adminUser.Id)
if err != nil {
log.Fatal(err)
}
mctx := context.WithValue(ctx, "cerberusTokenPair", tokenPair)
err = cerberusClient.ExecuteWithCtx(mctx,
cerberusClient.CreateAccountCmd(account.Id),
cerberusClient.CreateSuperRoleCmd(common.AccountAdministrator_R),
cerberusClient.CreateUserCmd(adminUser.Id, adminUser.Email, adminUser.Name),
cerberusClient.AssignRoleCmd(common.AccountAdministrator_R, adminUser.Id),
cerberusClient.CreateResourceCmd(account.Id, "", common.Account_RT),
cerberusClient.CreateRolePermissionCmd(common.AccountAdministrator_R, account.Id, []string{common.CanManageAccount_P}))
if err != nil {
log.Fatal(err)
}
// all users
users, err := userRepo.FindAll(account.Id)
if err != nil {
log.Fatal(err)
}
for _, user := range users {
err = cerberusClient.ExecuteWithCtx(mctx,
cerberusClient.CreateUserCmd(user.Id, user.Email, user.Name))
if err != nil {
log.Fatal(err)
}
}
// projects
projects, err := projectRepo.FindByAccount(account.Id)
if err != nil {
log.Fatal(err)
}
for _, project := range projects {
err = cerberusClient.ExecuteWithCtx(mctx,
cerberusClient.CreateResourceCmd(project.Id, account.Id, common.Project_RT))
if err != nil {
log.Fatal(err)
}
// sprints
sprints, err := sprintRepo.FindByProject(project.Id)
if err != nil {
log.Fatal(err)
}
for _, sprint := range sprints {
err = cerberusClient.ExecuteWithCtx(mctx,
cerberusClient.CreateResourceCmd(sprint.Id, project.Id, common.Sprint_RT))
if err != nil {
log.Fatal(err)
}
// stories
stories, err := storyRepo.FindBySprint(sprint.Id)
if err != nil {
log.Fatal(err)
}
for _, story := range stories {
err = cerberusClient.ExecuteWithCtx(mctx,
cerberusClient.CreateResourceCmd(story.Id, sprint.Id, common.Story_RT))
if err != nil {
log.Fatal(err)
}
}
}
}
}
This will migrate any existing resources and users you've created into cerberus. IMPORTANT!! replace the "admin" user lookup with a user of your own that you've created.
Don't worry about the details of this code. It simply loops through local data and creates corresponding users and resources in cerberus.
All commands in cerberus are idempotent, so this code can run multiple times without problems.
This type of approach is useful when you have an existing production app that you'd like to migrate to cerberus.
Last updated