mirror of https://github.com/knative/pkg.git
Source validation fixes (#2251)
* added basic structure for source validation * added validation to the sources.spec.ceOverrides.extensions field * added multi function validation acording to the spec field thats been validated * added tests to source types validation * added full coverage to validation cases * updated codegen and dependencies * fixed deepcopy not been generated + added link and explanation for the maxExtensionNameLength in cloud events * removed extension name length because is a SHOULD not a MUST * removed extension name length because is a SHOULD not a MUST * fixed copyright dates on edited files * fixed error message and header copyright year in pr comments * fixed unnecesary method ValidateSource * fixed pr comments * fixed deprecated method used on apis/duck/ABOUT.md * updated tests names to match the spec * fixed error message * added key keyword to test to description * fixed extension keys validation error message
This commit is contained in:
parent
fb7ee28566
commit
d4505c6605
|
@ -302,7 +302,11 @@ is used with duck types:
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
logger := c.Logger.Named("Revisions")
|
logger := c.Logger.Named("Revisions")
|
||||||
impl := controller.NewImpl(c, logger, "Revisions")
|
impl := controller.NewContext(
|
||||||
|
ctx,
|
||||||
|
c,
|
||||||
|
controller.ControllerOptions{WorkQueueName: "Revisions", Logger: logger},
|
||||||
|
)
|
||||||
|
|
||||||
// Calls to Track create a 30 minute lease before they must be renewed.
|
// Calls to Track create a 30 minute lease before they must be renewed.
|
||||||
// Coordinate this value with controller resync periods.
|
// Coordinate this value with controller resync periods.
|
||||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
@ -170,3 +171,45 @@ type SourceList struct {
|
||||||
|
|
||||||
Items []Source `json:"items"`
|
Items []Source `json:"items"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Source) Validate(ctx context.Context) *apis.FieldError {
|
||||||
|
if s == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return s.Spec.Validate(ctx).ViaField("spec")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SourceSpec) Validate(ctx context.Context) *apis.FieldError {
|
||||||
|
return s.CloudEventOverrides.Validate(ctx).ViaField("ceOverrides")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ceOverrides *CloudEventOverrides) Validate(ctx context.Context) *apis.FieldError {
|
||||||
|
for key := range ceOverrides.Extensions {
|
||||||
|
if err := validateExtensionName(key); err != nil {
|
||||||
|
return err.ViaField("extensions")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateExtensionName(key string) *apis.FieldError {
|
||||||
|
if key == "" {
|
||||||
|
return apis.ErrInvalidKeyName(
|
||||||
|
key,
|
||||||
|
"",
|
||||||
|
"keys MUST NOT be empty",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range key {
|
||||||
|
if !((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) {
|
||||||
|
return apis.ErrInvalidKeyName(
|
||||||
|
key,
|
||||||
|
"",
|
||||||
|
"keys are expected to be alphanumeric",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
Copyright 2021 The Knative Authors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"knative.dev/pkg/apis"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSourceValidate(t *testing.T) {
|
||||||
|
for _, tt := range []struct {
|
||||||
|
name string
|
||||||
|
src *Source
|
||||||
|
want *apis.FieldError
|
||||||
|
}{{
|
||||||
|
name: "empty source validation",
|
||||||
|
src: nil,
|
||||||
|
want: nil,
|
||||||
|
}, {
|
||||||
|
name: "empty source ceOverrides extensions validation",
|
||||||
|
src: &Source{Spec: SourceSpec{
|
||||||
|
CloudEventOverrides: &CloudEventOverrides{Extensions: map[string]string{}},
|
||||||
|
}},
|
||||||
|
want: nil,
|
||||||
|
}, {
|
||||||
|
name: "empty extension name error",
|
||||||
|
src: &Source{Spec: SourceSpec{
|
||||||
|
CloudEventOverrides: &CloudEventOverrides{Extensions: map[string]string{"": "test"}},
|
||||||
|
}},
|
||||||
|
want: apis.ErrInvalidKeyName(
|
||||||
|
"",
|
||||||
|
"spec.ceOverrides.extensions",
|
||||||
|
"keys MUST NOT be empty",
|
||||||
|
),
|
||||||
|
}, {
|
||||||
|
name: "long extension key name is valid",
|
||||||
|
src: &Source{Spec: SourceSpec{
|
||||||
|
CloudEventOverrides: &CloudEventOverrides{
|
||||||
|
Extensions: map[string]string{"nameLongerThan20Characters": "test"},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
want: nil,
|
||||||
|
}, {
|
||||||
|
name: "invalid extension name",
|
||||||
|
src: &Source{Spec: SourceSpec{
|
||||||
|
CloudEventOverrides: &CloudEventOverrides{Extensions: map[string]string{"invalid_name": "test"}},
|
||||||
|
}},
|
||||||
|
want: apis.ErrInvalidKeyName(
|
||||||
|
"invalid_name",
|
||||||
|
"spec.ceOverrides.extensions",
|
||||||
|
"keys are expected to be alphanumeric",
|
||||||
|
),
|
||||||
|
}, {
|
||||||
|
name: "valid extension name",
|
||||||
|
src: &Source{Spec: SourceSpec{
|
||||||
|
CloudEventOverrides: &CloudEventOverrides{
|
||||||
|
Extensions: map[string]string{"validName": "test"},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
want: nil,
|
||||||
|
}} {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
tt := tt
|
||||||
|
t.Parallel()
|
||||||
|
got := tt.src.Validate(context.TODO())
|
||||||
|
if tt.want != nil && got.Error() != tt.want.Error() {
|
||||||
|
t.Errorf("Unexpected error want:\n%+s\ngot:\n%+s", tt.want, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.want == nil && got != nil {
|
||||||
|
t.Errorf("Unexpected error want:\nnil\ngot:\n%+s", got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue