Skip to content

Commit e583b53

Browse files
dpeckettDamian Peckett
andauthored
[METAL-1881] Remove naive mysql idenitifer limits (#33)
Co-authored-by: Damian Peckett <damian.peckett@kloeckner.com>
1 parent 53bc8ed commit e583b53

7 files changed

Lines changed: 65 additions & 20 deletions

File tree

pkg/controller/database/databaseHelper.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,13 @@ func parseDatabaseSecretData(dbcr *kciv1alpha1.Database, data map[string][]byte)
133133
}
134134

135135
func generateDatabaseSecretData(dbcr *kciv1alpha1.Database) (map[string][]byte, error) {
136+
const (
137+
// https://dev.mysql.com/doc/refman/5.7/en/identifier-length.html
138+
mysqlDBNameLengthLimit = 63
139+
// https://dev.mysql.com/doc/refman/5.7/en/replication-features-user-names.html
140+
mysqlUserLengthLimit = 32
141+
)
142+
136143
engine, err := dbcr.GetEngineType()
137144
if err != nil {
138145
return nil, err
@@ -151,8 +158,8 @@ func generateDatabaseSecretData(dbcr *kciv1alpha1.Database) (map[string][]byte,
151158
return data, nil
152159
case "mysql":
153160
data := map[string][]byte{
154-
"DB": []byte(stringShortner(dbName)),
155-
"USER": []byte(stringShortner(dbUser)),
161+
"DB": []byte(kci.StringSanitize(dbName, mysqlDBNameLengthLimit)),
162+
"USER": []byte(kci.StringSanitize(dbUser, mysqlUserLengthLimit)),
156163
"PASSWORD": []byte(dbPassword)}
157164
return data, nil
158165
default:

pkg/controller/database/helper.go

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
package database
22

33
import (
4-
"crypto/md5"
5-
"fmt"
64
kciv1alpha1 "github.com/kloeckner-i/db-operator/pkg/apis/kci/v1alpha1"
75
"github.com/kloeckner-i/db-operator/pkg/utils/kci"
8-
"io"
96
)
107

118
func isSpecChanged(dbcr *kciv1alpha1.Database) bool {
@@ -26,13 +23,6 @@ func addSpecChecksum(dbcr *kciv1alpha1.Database) {
2623
dbcr.ObjectMeta.SetAnnotations(annotations)
2724
}
2825

29-
func stringShortner(s string) string {
30-
h := md5.New()
31-
io.WriteString(h, s)
32-
str := fmt.Sprintf("%x", h.Sum(nil))
33-
return str[0:16]
34-
}
35-
3626
func containsString(slice []string, s string) bool {
3727
for _, item := range slice {
3828
if item == s {

pkg/controller/database/helper_test.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,3 @@ func TestIsSpecChanged(t *testing.T) {
8282
change := isSpecChanged(db)
8383
assert.Equal(t, change, true, "expected true")
8484
}
85-
86-
func TestStringShortner(t *testing.T) {
87-
assert.Equal(t, "e08ba29f56785332", stringShortner("short_string"))
88-
assert.Equal(t, "8f54fbbc6fefae00", stringShortner("short_string_longer"))
89-
assert.Equal(t, "f32225e6124f2fab", stringShortner("short_string_to_long_to_see_all_chars_in_result"))
90-
}

pkg/controller/database/monitoring/database.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import (
55

66
kciv1alpha1 "github.com/kloeckner-i/db-operator/pkg/apis/kci/v1alpha1"
77

8-
v1 "k8s.io/api/core/v1"
98
v1apps "k8s.io/api/apps/v1"
9+
v1 "k8s.io/api/core/v1"
1010
)
1111

1212
// Deployment builds kubernetes deployment object

pkg/controller/database/monitoring/test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import (
77

88
"bou.ke/monkey"
99
"github.com/stretchr/testify/assert"
10-
v1 "k8s.io/api/core/v1"
1110
v1apps "k8s.io/api/apps/v1"
11+
v1 "k8s.io/api/core/v1"
1212
)
1313

1414
func testPGDeployment(t *testing.T) {

pkg/utils/kci/database.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package kci
2+
3+
import (
4+
"crypto/sha256"
5+
"fmt"
6+
"regexp"
7+
"strings"
8+
)
9+
10+
// StringSanitize sanitizes and truncates a string to a fixed length using a hash function.
11+
// useful for restricting the length and content of user supplied database identifiers.
12+
func StringSanitize(s string, limit int) string {
13+
// use lowercase exclusively for identifiers.
14+
// https://dev.mysql.com/doc/refman/5.7/en/identifier-case-sensitivity.html
15+
s = strings.ToLower(s)
16+
17+
// Strip out any unsupported characters.
18+
// https://dev.mysql.com/doc/refman/5.7/en/identifiers.html
19+
unsupportedChars := regexp.MustCompile(`[^0-9a-zA-Z$_]`)
20+
s = unsupportedChars.ReplaceAllString(s, "_")
21+
22+
if len(s) <= limit {
23+
return s
24+
}
25+
26+
if limit <= 9 {
27+
return fmt.Sprintf("%x", sha256.New().Sum([]byte(s)))[:limit]
28+
}
29+
30+
return fmt.Sprintf("%s_%x", s[:limit-9], sha256.New().Sum([]byte(s))[:4])
31+
}

pkg/utils/kci/database_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package kci
2+
3+
import (
4+
"github.com/stretchr/testify/assert"
5+
"testing"
6+
)
7+
8+
func TestStringSanitize(t *testing.T) {
9+
// Handles very short limits
10+
src := "HelloWorld"
11+
actual := StringSanitize(src, 6)
12+
assert.Equal(t, "68656c", actual)
13+
14+
// Sanitizes successfully
15+
src = "Hello**World$"
16+
actual = StringSanitize(src, 32)
17+
assert.Equal(t, "hello__world$", actual)
18+
19+
// Truncates very long values
20+
src = "The quick brown fox jumps over the lazy dog"
21+
actual = StringSanitize(src, 32)
22+
assert.Equal(t, "the_quick_brown_fox_jum_7468655f", actual)
23+
}

0 commit comments

Comments
 (0)