@@ -19,11 +19,14 @@ package validations
19
19
import (
20
20
"bufio"
21
21
"fmt"
22
+ "io/ioutil"
22
23
"net/http"
23
24
"os"
24
25
"regexp"
25
26
"sort"
26
27
"strings"
28
+
29
+ "sigs.k8s.io/yaml"
27
30
)
28
31
29
32
type KeyMustBeSpecified struct {
@@ -86,7 +89,10 @@ func (m *MustHaveAtLeastOneValue) Error() string {
86
89
return fmt .Sprintf ("%q must have at least one value" , m .key )
87
90
}
88
91
89
- var listGroups []string
92
+ var (
93
+ listGroups []string
94
+ prrApprovers []string
95
+ )
90
96
91
97
func init () {
92
98
resp , err := http .Get ("https://raw.githubusercontent.com/kubernetes/community/master/sigs.yaml" )
@@ -113,6 +119,34 @@ func init() {
113
119
os .Exit (1 )
114
120
}
115
121
sort .Strings (listGroups )
122
+
123
+ resp , err = http .Get ("https://raw.githubusercontent.com/kubernetes/enhancements/master/OWNERS_ALIASES" )
124
+ if err != nil {
125
+ fmt .Fprintf (os .Stderr , "unable to fetch list of aliases: %v\n " , err )
126
+ os .Exit (1 )
127
+ }
128
+ defer resp .Body .Close ()
129
+ if resp .StatusCode != http .StatusOK {
130
+ fmt .Fprintf (os .Stderr , "invalid status code when fetching list of aliases: %d\n " , resp .StatusCode )
131
+ os .Exit (1 )
132
+ }
133
+
134
+ body , err := ioutil .ReadAll (resp .Body )
135
+ if err != nil {
136
+ fmt .Fprintf (os .Stderr , "unable to read aliases content: %v\n " , err )
137
+ os .Exit (1 )
138
+ }
139
+ config := & struct {
140
+ Data map [string ][]string `json:"aliases,omitempty"`
141
+ }{}
142
+ if err := yaml .Unmarshal (body , config ); err != nil {
143
+ fmt .Fprintf (os .Stderr , "unable to read parse aliases content: %v\n " , err )
144
+ os .Exit (1 )
145
+ }
146
+ for _ , approver := range config .Data ["prod-readiness-approvers" ] {
147
+ prrApprovers = append (prrApprovers , approver )
148
+ }
149
+ sort .Strings (listGroups )
116
150
}
117
151
118
152
var (
@@ -219,6 +253,24 @@ func ValidateStructure(parsed map[interface{}]interface{}) error {
219
253
case interface {}:
220
254
return & ValueMustBeListOfStrings {k , values }
221
255
}
256
+ case "prr-approvers" :
257
+ switch values := value .(type ) {
258
+ case []interface {}:
259
+ for _ , value := range values {
260
+ v := value .(string )
261
+ if len (v ) > 0 && v [0 ] == '@' {
262
+ // If "@" is appeneded at the beginning, remove it.
263
+ v = v [1 :]
264
+ }
265
+
266
+ index := sort .SearchStrings (prrApprovers , v )
267
+ if index >= len (prrApprovers ) || prrApprovers [index ] != v {
268
+ return & ValueMustBeOneOf {k , v , prrApprovers }
269
+ }
270
+ }
271
+ case interface {}:
272
+ return & ValueMustBeListOfStrings {k , values }
273
+ }
222
274
}
223
275
}
224
276
return nil
0 commit comments