Skip to content

Commit 8ffe0d2

Browse files
committed
api: Validate PRRs by field
Signed-off-by: Stephen Augustus <[email protected]>
1 parent 7fb91eb commit 8ffe0d2

File tree

6 files changed

+105
-15
lines changed

6 files changed

+105
-15
lines changed

api/approval.go

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,16 @@ limitations under the License.
1616

1717
package api
1818

19+
import (
20+
"bufio"
21+
"bytes"
22+
"io"
23+
24+
"github.com/go-playground/validator/v10"
25+
"github.com/pkg/errors"
26+
"gopkg.in/yaml.v3"
27+
)
28+
1929
type PRRApprovals []*PRRApproval
2030

2131
func (p *PRRApprovals) AddPRRApproval(prrApproval *PRRApproval) {
@@ -28,23 +38,62 @@ type PRRApproval struct {
2838
Beta PRRMilestone `json:"beta" yaml:"beta,omitempty"`
2939
Stable PRRMilestone `json:"stable" yaml:"stable,omitempty"`
3040

41+
// TODO(api): Move to separate struct for handling document parsing
3142
Error error `json:"-" yaml:"-"`
3243
}
3344

34-
func (p *PRRApproval) ApproverForStage(stage string) string {
45+
func (prr *PRRApproval) Validate() error {
46+
v := validator.New()
47+
if err := v.Struct(prr); err != nil {
48+
return errors.Wrap(err, "running validation")
49+
}
50+
51+
return nil
52+
}
53+
54+
func (prr *PRRApproval) ApproverForStage(stage string) string {
3555
switch stage {
3656
case "alpha":
37-
return p.Alpha.Approver
57+
return prr.Alpha.Approver
3858
case "beta":
39-
return p.Beta.Approver
59+
return prr.Beta.Approver
4060
case "stable":
41-
return p.Stable.Approver
61+
return prr.Stable.Approver
4262
}
4363

4464
return ""
4565
}
4666

4767
// TODO(api): Can we refactor the proposal `Milestone` to retrieve this?
4868
type PRRMilestone struct {
49-
Approver string `json:"approver" yaml:"approver"`
69+
Approver string `json:"approver" yaml:"approver" validate:"required"`
70+
}
71+
72+
type PRRHandler Parser
73+
74+
// TODO(api): Make this a generic parser for all `Document` types
75+
func (p *PRRHandler) Parse(in io.Reader) (*PRRApproval, error) {
76+
scanner := bufio.NewScanner(in)
77+
var body bytes.Buffer
78+
for scanner.Scan() {
79+
line := scanner.Text() + "\n"
80+
body.WriteString(line)
81+
}
82+
83+
approval := &PRRApproval{}
84+
if err := scanner.Err(); err != nil {
85+
return approval, errors.Wrap(err, "reading file")
86+
}
87+
88+
if err := yaml.Unmarshal(body.Bytes(), &approval); err != nil {
89+
p.Errors = append(p.Errors, errors.Wrap(err, "error unmarshalling YAML"))
90+
return approval, errors.Wrap(err, "unmarshalling YAML")
91+
}
92+
93+
if valErr := approval.Validate(); valErr != nil {
94+
p.Errors = append(p.Errors, errors.Wrap(valErr, "validating PRR"))
95+
return approval, errors.Wrap(valErr, "validating PRR")
96+
}
97+
98+
return approval, nil
5099
}

api/document.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,26 @@ limitations under the License.
1616

1717
package api
1818

19+
import (
20+
"io"
21+
)
22+
1923
// TODO(api): Populate interface
2024
// TODO(api): Mock interface
21-
type Document interface{}
25+
type File interface {
26+
Parse(io.Reader) (Document, error)
27+
}
28+
29+
// TODO(api): Populate interface
30+
// TODO(api): Mock interface
31+
// Document is an interface satisfied by the following types:
32+
// - `Proposal` (KEP)
33+
// - `PRRApproval`
34+
// - `Receipt` (coming soon)
35+
type Document interface {
36+
Validate() error
37+
}
38+
39+
type Parser struct {
40+
Errors []error
41+
}

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ module k8s.io/enhancements
33
go 1.15
44

55
require (
6+
github.com/go-playground/validator/v10 v10.4.1
67
github.com/google/go-github/v32 v32.1.0
8+
github.com/leodido/go-urn v1.2.1 // indirect
79
github.com/maxbrunsfeld/counterfeiter/v6 v6.3.0
810
github.com/olekukonko/tablewriter v0.0.4
911
github.com/pkg/errors v0.9.1
1012
github.com/psampaz/go-mod-outdated v0.7.0
1113
github.com/sirupsen/logrus v1.7.0
1214
github.com/spf13/cobra v1.1.1
13-
github.com/spf13/pflag v1.0.5
1415
github.com/stretchr/testify v1.7.0
1516
golang.org/x/oauth2 v0.0.0-20210112200429-01de73cf58bd
1617
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c

go.sum

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,14 @@ github.com/go-openapi/validate v0.17.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+
482482
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
483483
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
484484
github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
485+
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
486+
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
487+
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
488+
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
489+
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
490+
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
491+
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
492+
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
485493
github.com/go-sql-driver/mysql v0.0.0-20160411075031-7ebe0a500653/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
486494
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
487495
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
@@ -822,6 +830,9 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
822830
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
823831
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
824832
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
833+
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
834+
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
835+
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
825836
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
826837
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
827838
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=

pkg/legacy/keps/proposals.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import (
2828
"gopkg.in/yaml.v3"
2929

3030
"k8s.io/enhancements/api"
31-
"k8s.io/enhancements/pkg/legacy/keps/validations"
3231
)
3332

3433
type Parser struct{}
@@ -71,10 +70,12 @@ func (p *Parser) Parse(in io.Reader) *api.Proposal {
7170
return proposal
7271
}
7372

74-
if err := validations.ValidateStructure(test); err != nil {
75-
proposal.Error = errors.Wrap(err, "error validating KEP metadata")
76-
return proposal
77-
}
73+
/*
74+
if err := validations.ValidateStructure(test); err != nil {
75+
proposal.Error = errors.Wrap(err, "error validating KEP metadata")
76+
return proposal
77+
}
78+
*/
7879

7980
proposal.Error = yaml.Unmarshal(metadata, proposal)
8081
proposal.ID = hash(proposal.OwningSIG + ":" + proposal.Title)

test/metadata_test.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ import (
2222
"strings"
2323
"testing"
2424

25+
"github.com/stretchr/testify/require"
26+
27+
"k8s.io/enhancements/api"
2528
"k8s.io/enhancements/pkg/legacy/keps"
26-
"k8s.io/enhancements/pkg/legacy/prrs"
2729
)
2830

2931
const (
@@ -74,7 +76,7 @@ func TestValidation(t *testing.T) {
7476
}
7577

7678
kepParser := &keps.Parser{}
77-
prrParser := &prrs.Parser{}
79+
prrHandler := &api.PRRHandler{}
7880
prrsDir := filepath.Join("..", prrsDir)
7981

8082
for _, filename := range files {
@@ -83,6 +85,7 @@ func TestValidation(t *testing.T) {
8385
if err != nil {
8486
t.Fatalf("could not open file %s: %v\n", filename, err)
8587
}
88+
8689
defer kepFile.Close()
8790

8891
kep := kepParser.Parse(kepFile)
@@ -114,10 +117,14 @@ func TestValidation(t *testing.T) {
114117
t.Errorf("To get PRR approval modify appropriately file %s and have this approved by PRR team", prrFilename)
115118
return
116119
}
120+
117121
if err != nil {
118122
t.Fatalf("could not open file %s: %v\n", prrFilename, err)
119123
}
120-
prr := prrParser.Parse(prrFile)
124+
125+
prr, prrParseErr := prrHandler.Parse(prrFile)
126+
require.Nil(t, prrParseErr)
127+
121128
if prr.Error != nil {
122129
t.Errorf("PRR approval file %v has an error: %v", prrFilename, prr.Error)
123130
return
@@ -132,6 +139,7 @@ func TestValidation(t *testing.T) {
132139
case "stable":
133140
stagePRRApprover = prr.Stable.Approver
134141
}
142+
135143
if len(stageMilestone) > 0 && stageMilestone >= "v1.21" {
136144
// PRR approval is needed.
137145
if stagePRRApprover == "" {

0 commit comments

Comments
 (0)