1
16
17 package validation
18
19 import (
20 "fmt"
21 "strings"
22
23 apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation"
24 "k8s.io/apimachinery/pkg/util/validation"
25 "k8s.io/apimachinery/pkg/util/validation/field"
26 )
27
28
29
30
31
32
33
34
35
36
37 func ValidateSignerName(fldPath *field.Path, signerName string) field.ErrorList {
38 var el field.ErrorList
39 if len(signerName) == 0 {
40 el = append(el, field.Required(fldPath, ""))
41 return el
42 }
43
44 segments := strings.Split(signerName, "/")
45
46
47 if len(segments) != 2 {
48 el = append(el, field.Invalid(fldPath, signerName, "must be a fully qualified domain and path of the form 'example.com/signer-name'"))
49
50
51 return el
52 }
53
54
55 maxDomainSegmentLength := validation.DNS1123SubdomainMaxLength
56 if len(segments[0]) > maxDomainSegmentLength {
57 el = append(el, field.TooLong(fldPath, segments[0], maxDomainSegmentLength))
58 }
59
60 domainLabels := strings.Split(segments[0], ".")
61 for _, lbl := range domainLabels {
62
63
64 if errs := validation.IsDNS1123Label(lbl); len(errs) > 0 {
65 for _, err := range errs {
66 el = append(el, field.Invalid(fldPath, segments[0], fmt.Sprintf("validating label %q: %s", lbl, err)))
67 }
68
69
70
71 break
72 }
73 }
74
75
76 if len(domainLabels) < 2 {
77 el = append(el, field.Invalid(fldPath, segments[0], "should be a domain with at least two segments separated by dots"))
78 }
79
80
81 pathLabels := strings.Split(segments[1], ".")
82 for _, lbl := range pathLabels {
83
84
85 if errs := validation.IsDNS1123Subdomain(lbl); len(errs) > 0 {
86 for _, err := range errs {
87 el = append(el, field.Invalid(fldPath, segments[1], fmt.Sprintf("validating label %q: %s", lbl, err)))
88 }
89
90
91
92 break
93 }
94 }
95
96
97 maxPathSegmentLength := validation.DNS1123SubdomainMaxLength + validation.DNS1123LabelMaxLength + 1
98 maxSignerNameLength := maxDomainSegmentLength + maxPathSegmentLength + 1
99 if len(signerName) > maxSignerNameLength {
100 el = append(el, field.TooLong(fldPath, signerName, maxSignerNameLength))
101 }
102
103 return el
104 }
105
106
107
108 func ValidateClusterTrustBundleName(signerName string) func(name string, prefix bool) []string {
109 return func(name string, isPrefix bool) []string {
110 if signerName == "" {
111 if strings.Contains(name, ":") {
112 return []string{"ClusterTrustBundle without signer name must not have \":\" in its name"}
113 }
114 return apimachineryvalidation.NameIsDNSSubdomain(name, isPrefix)
115 }
116
117 requiredPrefix := strings.ReplaceAll(signerName, "/", ":") + ":"
118 if !strings.HasPrefix(name, requiredPrefix) {
119 return []string{fmt.Sprintf("ClusterTrustBundle for signerName %s must be named with prefix %s", signerName, requiredPrefix)}
120 }
121 return apimachineryvalidation.NameIsDNSSubdomain(strings.TrimPrefix(name, requiredPrefix), isPrefix)
122 }
123 }
124
125 func extractSignerNameFromClusterTrustBundleName(name string) (string, bool) {
126 if splitPoint := strings.LastIndex(name, ":"); splitPoint != -1 {
127
128 return strings.ReplaceAll(name[:splitPoint], ":", "/"), true
129 } else {
130 return "", false
131 }
132 }
133
View as plain text