-
Notifications
You must be signed in to change notification settings - Fork 333
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(MeshHTTPRoute): add basic validation (#5625)
Signed-off-by: Mike Beaumont <mjboamail@gmail.com>
- Loading branch information
1 parent
e6552b6
commit 8e2cf89
Showing
7 changed files
with
210 additions
and
118 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
pkg/plugins/policies/meshhttproute/api/v1alpha1/v1alpha1_suite_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package v1alpha1_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/kumahq/kuma/pkg/test" | ||
) | ||
|
||
func TestPlugin(t *testing.T) { | ||
test.RunSpecs(t, "MeshHTTPRoute") | ||
} |
44 changes: 44 additions & 0 deletions
44
pkg/plugins/policies/meshhttproute/api/v1alpha1/validation.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package v1alpha1 | ||
|
||
import ( | ||
common_api "github.com/kumahq/kuma/api/common/v1alpha1" | ||
"github.com/kumahq/kuma/pkg/core/validators" | ||
matcher_validators "github.com/kumahq/kuma/pkg/plugins/policies/matchers/validators" | ||
) | ||
|
||
func (r *MeshHTTPRouteResource) validate() error { | ||
var verr validators.ValidationError | ||
path := validators.RootedAt("spec") | ||
verr.AddErrorAt(path.Field("targetRef"), validateTop(r.Spec.TargetRef)) | ||
verr.AddErrorAt(path.Field("to"), validateRules(r.Spec.To)) | ||
return verr.OrNil() | ||
} | ||
|
||
func validateTop(targetRef common_api.TargetRef) validators.ValidationError { | ||
return matcher_validators.ValidateTargetRef(targetRef, &matcher_validators.ValidateTargetRefOpts{ | ||
SupportedKinds: []common_api.TargetRefKind{ | ||
common_api.Mesh, | ||
common_api.MeshSubset, | ||
common_api.MeshService, | ||
common_api.MeshServiceSubset, | ||
}, | ||
}) | ||
} | ||
|
||
func validateToRef(targetRef common_api.TargetRef) validators.ValidationError { | ||
return matcher_validators.ValidateTargetRef(targetRef, &matcher_validators.ValidateTargetRefOpts{ | ||
SupportedKinds: []common_api.TargetRefKind{ | ||
common_api.MeshService, | ||
}, | ||
}) | ||
} | ||
|
||
func validateRules(tos []To) validators.ValidationError { | ||
var errs validators.ValidationError | ||
|
||
for i, to := range tos { | ||
errs.AddErrorAt(validators.PathBuilder{}.Index(i).Field("targetRef"), validateToRef(to.TargetRef)) | ||
} | ||
|
||
return errs | ||
} |
56 changes: 56 additions & 0 deletions
56
pkg/plugins/policies/meshhttproute/api/v1alpha1/validation_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package v1alpha1_test | ||
|
||
import ( | ||
. "github.com/onsi/ginkgo/v2" | ||
|
||
"github.com/kumahq/kuma/pkg/core/validators" | ||
api "github.com/kumahq/kuma/pkg/plugins/policies/meshhttproute/api/v1alpha1" | ||
. "github.com/kumahq/kuma/pkg/test/resources" | ||
) | ||
|
||
var _ = Describe("validation", func() { | ||
DescribeErrorCases( | ||
api.NewMeshHTTPRouteResource, | ||
ErrorCase("spec.targetRef error", | ||
validators.Violation{ | ||
Field: `spec.targetRef.kind`, | ||
Message: `value is not supported`, | ||
}, ` | ||
type: MeshHTTPRoute | ||
mesh: mesh-1 | ||
name: route-1 | ||
targetRef: | ||
kind: BlahBlah | ||
name: frontend | ||
to: [] | ||
`), | ||
ErrorCase("spec.to.targetRef error", | ||
validators.Violation{ | ||
Field: `spec.to[0].targetRef.kind`, | ||
Message: `value is not supported`, | ||
}, ` | ||
type: MeshHTTPRoute | ||
mesh: mesh-1 | ||
name: route-1 | ||
targetRef: | ||
kind: MeshService | ||
name: frontend | ||
to: | ||
- targetRef: | ||
kind: BlahBlah | ||
name: frontend | ||
`), | ||
) | ||
DescribeValidCases( | ||
api.NewMeshHTTPRouteResource, | ||
Entry("accepts valid resource", ` | ||
type: MeshHTTPRoute | ||
mesh: mesh-1 | ||
name: route-1 | ||
targetRef: | ||
kind: MeshService | ||
name: frontend | ||
to: [] | ||
`), | ||
) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package resources | ||
|
||
import ( | ||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
|
||
core_model "github.com/kumahq/kuma/pkg/core/resources/model" | ||
"github.com/kumahq/kuma/pkg/core/validators" | ||
) | ||
|
||
// ResourceGenerator creates a resource of a pre-defined type. | ||
type ResourceGenerator interface { | ||
New() core_model.Resource | ||
} | ||
|
||
// ResourceValidationCase captures a resource YAML and any corresponding validation error. | ||
type ResourceValidationCase struct { | ||
Resource string | ||
Violations []validators.Violation | ||
} | ||
|
||
// DescribeValidCases creates a Ginkgo table test for the given entries, | ||
// where each entry is a valid YAML resource. It ensures that each entry | ||
// can be successfully validated. | ||
func DescribeValidCases[T core_model.Resource](generator func() T, cases ...TableEntry) { | ||
DescribeTable( | ||
"should pass validation", | ||
func(given string) { | ||
// setup | ||
resource := generator() | ||
|
||
// when | ||
err := core_model.FromYAML([]byte(given), resource.GetSpec()) | ||
|
||
// then | ||
Expect(err).ToNot(HaveOccurred()) | ||
|
||
// when | ||
verr := core_model.Validate(resource) | ||
|
||
// then | ||
Expect(verr).ToNot(HaveOccurred()) | ||
}, | ||
cases) | ||
} | ||
|
||
// DescribeErrorCases creates a Ginkgo table test for the given entries, where each entry | ||
// is a ResourceValidationCase that contains an invalid resource YAML and the corresponding | ||
// validation error. | ||
func DescribeErrorCases[T core_model.Resource](generator func() T, cases ...TableEntry) { | ||
DescribeTable( | ||
"should validate all fields and return as many individual errors as possible", | ||
func(given ResourceValidationCase) { | ||
// setup | ||
resource := generator() | ||
|
||
// when | ||
Expect( | ||
core_model.FromYAML([]byte(given.Resource), resource.GetSpec()), | ||
).ToNot(HaveOccurred()) | ||
|
||
expected := validators.ValidationError{ | ||
Violations: given.Violations, | ||
} | ||
|
||
// then | ||
err := core_model.Validate(resource).(*validators.ValidationError) | ||
Expect(err.Violations).To(ConsistOf(expected.Violations)) | ||
}, | ||
cases, | ||
) | ||
} | ||
|
||
// ErrorCase is a helper that generates a table entry for DescribeErrorCases. | ||
func ErrorCase(description string, err validators.Violation, yaml string) TableEntry { | ||
return Entry( | ||
description, | ||
ResourceValidationCase{ | ||
Violations: []validators.Violation{err}, | ||
Resource: yaml, | ||
}, | ||
) | ||
} | ||
|
||
func ErrorCases(description string, errs []validators.Violation, yaml string) TableEntry { | ||
return Entry( | ||
description, | ||
ResourceValidationCase{ | ||
Violations: errs, | ||
Resource: yaml, | ||
}, | ||
) | ||
} |