-
Notifications
You must be signed in to change notification settings - Fork 88
/
migrator.go
202 lines (176 loc) · 6.33 KB
/
migrator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package mysql
import (
"strings"
"github.com/cloudflare/cfssl/log"
"github.com/kfsoftware/hlf-operator/internal/github.com/hyperledger/fabric-ca/lib/server/db"
"github.com/kfsoftware/hlf-operator/internal/github.com/hyperledger/fabric-ca/lib/server/db/util"
"github.com/kfsoftware/hlf-operator/internal/github.com/hyperledger/fabric-ca/lib/server/user"
"github.com/pkg/errors"
)
// Migrator defines migrator
type Migrator struct {
Tx db.FabricCATx
CurLevels *util.Levels
SrvLevels *util.Levels
}
// NewMigrator returns a migrator instance
func NewMigrator(tx db.FabricCATx, curLevels, srvLevels *util.Levels) *Migrator {
return &Migrator{
Tx: tx,
CurLevels: curLevels,
SrvLevels: srvLevels,
}
}
// MigrateUsersTable is responsible for migrating users table
func (m *Migrator) MigrateUsersTable() error {
tx := m.Tx
const funcName = "MigrateUsersTable"
// Future schema updates should add to the logic below to handle other levels
switch m.CurLevels.Identity {
case 0:
log.Debug("Upgrade identity table to level 1")
_, err := tx.Exec(funcName, "ALTER TABLE users MODIFY id VARCHAR(255), MODIFY type VARCHAR(256), MODIFY affiliation VARCHAR(1024)")
if err != nil {
return err
}
_, err = tx.Exec(funcName, "ALTER TABLE users MODIFY attributes TEXT")
if err != nil {
return err
}
_, err = tx.Exec(funcName, "ALTER TABLE users ADD COLUMN level INTEGER DEFAULT 0 AFTER max_enrollments")
if err != nil && !strings.Contains(err.Error(), "1060") { // Already using the latest schema
return err
}
fallthrough
case 1:
log.Debug("Upgrade identity table to level 2")
_, err := tx.Exec(funcName, "ALTER TABLE users ADD COLUMN incorrect_password_attempts INTEGER DEFAULT 0 AFTER level")
if err != nil && !strings.Contains(err.Error(), "1060") { // Already using the latest schema
return err
}
fallthrough
default:
users, err := user.GetUserLessThanLevel(tx, m.SrvLevels.Identity)
if err != nil {
return err
}
for _, u := range users {
err := u.Migrate(tx)
if err != nil {
return err
}
}
_, err = tx.Exec(funcName, tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'identity.level')"), m.SrvLevels.Identity)
if err != nil {
return err
}
return nil
}
}
// MigrateCertificatesTable is responsible for migrating certificates table
func (m *Migrator) MigrateCertificatesTable() error {
tx := m.Tx
const funcName = "MigrateCertificatesTable"
// Future schema updates should add to the logic below to handle other levels
switch m.CurLevels.Certificate {
case 0:
log.Debug("Upgrade certificates table to level 1")
_, err := tx.Exec(funcName, "ALTER TABLE certificates ADD COLUMN level INTEGER DEFAULT 0 AFTER pem")
if err != nil {
if !strings.Contains(err.Error(), "1060") { // Already using the latest schema
return err
}
}
_, err = tx.Exec(funcName, "ALTER TABLE certificates MODIFY id VARCHAR(255)")
if err != nil {
return err
}
fallthrough
case 1:
log.Debug("Upgrade certificates table to level 2")
_, err := tx.Exec(funcName, "ALTER TABLE certificates MODIFY pem varbinary(8192)")
if err != nil {
return err
}
fallthrough
default:
_, err := tx.Exec(funcName, tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'certificate.level')"), m.SrvLevels.Certificate)
if err != nil {
return err
}
return nil
}
}
// MigrateAffiliationsTable is responsible for migrating affiliations table
func (m *Migrator) MigrateAffiliationsTable() error {
tx := m.Tx
const funcName = "MigrateAffiliationsTable"
// Future schema updates should add to the logic below to handle other levels
switch m.CurLevels.Affiliation {
case 0:
log.Debug("Upgrade affiliations table to level 1")
_, err := tx.Exec(funcName, "ALTER TABLE affiliations ADD COLUMN level INTEGER DEFAULT 0 AFTER prekey")
if err != nil && !strings.Contains(err.Error(), "1060") { // Already using the latest schema
return err
}
_, err = tx.Exec(funcName, "ALTER TABLE affiliations DROP INDEX name;")
if err != nil && !strings.Contains(err.Error(), "Error 1091") { // Indicates that index not found
return err
}
_, err = tx.Exec(funcName, "ALTER TABLE affiliations ADD COLUMN id INT NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST")
if err != nil && !strings.Contains(err.Error(), "1060") { // Already using the latest schema
return err
}
_, err = tx.Exec(funcName, "ALTER TABLE affiliations MODIFY name VARCHAR(1024), MODIFY prekey VARCHAR(1024)")
if err != nil {
return err
}
_, err = tx.Exec(funcName, "ALTER TABLE affiliations ADD INDEX name_index (name)")
if err != nil && !strings.Contains(err.Error(), "Error 1061") { // Error 1061: Duplicate key name, index already exists
return err
}
fallthrough
default:
_, err := tx.Exec(funcName, tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'affiliation.level')"), m.SrvLevels.Affiliation)
if err != nil {
return err
}
return nil
}
}
// MigrateCredentialsTable is responsible for migrating credentials table
func (m *Migrator) MigrateCredentialsTable() error {
_, err := m.Tx.Exec("MigrateCredentialsTable", m.Tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'credential.level')"), m.SrvLevels.Credential)
return err
}
// MigrateRAInfoTable is responsible for migrating rainfo table
func (m *Migrator) MigrateRAInfoTable() error {
_, err := m.Tx.Exec("MigrateRAInfoTable", m.Tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'rcinfo.level')"), m.SrvLevels.RAInfo)
return err
}
// MigrateNoncesTable is responsible for migrating nonces table
func (m *Migrator) MigrateNoncesTable() error {
_, err := m.Tx.Exec("MigrateNoncesTable", m.Tx.Rebind("UPDATE properties SET value = ? WHERE (property = 'nonce.level')"), m.SrvLevels.Nonce)
return err
}
// Rollback is responsible for rollback transaction if an error is encountered
func (m *Migrator) Rollback() error {
err := m.Tx.Rollback("Migration")
if err != nil {
log.Errorf("Error encountered while rolling back database migration changes: %s", err)
return err
}
return nil
}
// Commit is responsible for committing the migration db transcation
func (m *Migrator) Commit() error {
err := m.Tx.Commit("Migration")
if err != nil {
return errors.Wrap(err, "Error encountered while committing database migration changes")
}
return nil
}