-
Notifications
You must be signed in to change notification settings - Fork 24
/
storage.go
117 lines (98 loc) · 3.39 KB
/
storage.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
package v1alpha1
import (
"fmt"
"net/url"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/validation/field"
)
// ValidateStorageSecret validates the object storage secret required for tempo.
func ValidateStorageSecret(tempo TempoStack, storageSecret corev1.Secret) field.ErrorList {
path := field.NewPath("spec").Child("storage").Child("secret")
if storageSecret.Data == nil {
return field.ErrorList{field.Invalid(path, tempo.Spec.Storage.Secret, "storage secret is empty")}
}
var allErrs field.ErrorList
switch tempo.Spec.Storage.Secret.Type {
case ObjectStorageSecretAzure:
allErrs = append(allErrs, validateAzureSecret(tempo, path, storageSecret)...)
case ObjectStorageSecretGCS:
allErrs = append(allErrs, validateGCSSecret(tempo, path, storageSecret)...)
case ObjectStorageSecretS3:
allErrs = append(allErrs, validateS3Secret(tempo, path, storageSecret)...)
case "":
allErrs = append(allErrs, field.Invalid(
path,
tempo.Spec.Storage.Secret,
"storage secret must specify the type",
))
default:
allErrs = append(allErrs, field.Invalid(
path,
tempo.Spec.Storage.Secret,
fmt.Sprintf("%s is not an allowed storage secret type", tempo.Spec.Storage.Secret.Type),
))
}
return allErrs
}
// ValidateStorageCAConfigMap validates the CA config map for accessing object storage.
func ValidateStorageCAConfigMap(caConfigMap corev1.ConfigMap) field.ErrorList {
path := field.NewPath("spec").Child("storage").Child("tls").Child("caName")
if caConfigMap.Data["ca.crt"] == "" {
return field.ErrorList{field.Invalid(path, caConfigMap.Name, "ConfigMap must contain a 'ca.crt' key")}
}
return nil
}
func ensureNotEmpty(tempo TempoStack, path *field.Path, storageSecret corev1.Secret, fields []string) field.ErrorList {
var allErrs field.ErrorList
for _, key := range fields {
if storageSecret.Data[key] == nil || len(storageSecret.Data[key]) == 0 {
allErrs = append(allErrs, field.Invalid(
path,
tempo.Spec.Storage.Secret,
fmt.Sprintf("storage secret must contain \"%s\" field", key),
))
}
}
return allErrs
}
func validateAzureSecret(tempo TempoStack, path *field.Path, storageSecret corev1.Secret) field.ErrorList {
var allErrs field.ErrorList
secretFields := []string{
"container",
"account_name",
"account_key",
}
allErrs = append(allErrs, ensureNotEmpty(tempo, path, storageSecret, secretFields)...)
return allErrs
}
func validateGCSSecret(tempo TempoStack, path *field.Path, storageSecret corev1.Secret) field.ErrorList {
var allErrs field.ErrorList
secretFields := []string{
"bucketname",
"key.json",
}
allErrs = append(allErrs, ensureNotEmpty(tempo, path, storageSecret, secretFields)...)
return allErrs
}
func validateS3Secret(tempo TempoStack, path *field.Path, storageSecret corev1.Secret) field.ErrorList {
var allErrs field.ErrorList
secretFields := []string{
"endpoint",
"bucket",
"access_key_id",
"access_key_secret",
}
allErrs = append(allErrs, ensureNotEmpty(tempo, path, storageSecret, secretFields)...)
if endpoint, ok := storageSecret.Data["endpoint"]; ok {
u, err := url.ParseRequestURI(string(endpoint))
// ParseRequestURI also accepts absolute paths, therefore we need to check if the URL scheme is set
if err != nil || u.Scheme == "" {
allErrs = append(allErrs, field.Invalid(
path,
tempo.Spec.Storage.Secret,
"\"endpoint\" field of storage secret must be a valid URL",
))
}
}
return allErrs
}