Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions pkg/profiles/profiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ var (
minStatus uint32 = 100
maxStatus uint32 = 599

errNilMatchAll = fmt.Errorf("null condition \"all\"")
errNilMatchAny = fmt.Errorf("null condition \"any\"")
errRequestMatchField = errors.New("A request match must have a field set")
errResponseMatchField = errors.New("A response match must have a field set")
)
Expand Down Expand Up @@ -66,6 +68,9 @@ func Validate(data []byte) error {
}

for _, route := range serviceProfile.Spec.Routes {
if route == nil {
return fmt.Errorf("ServiceProfile %q has a null route", serviceProfile.Name)
}
if route.Name == "" {
return fmt.Errorf("ServiceProfile %q has a route with no name", serviceProfile.Name)
}
Expand All @@ -83,6 +88,9 @@ func Validate(data []byte) error {
return fmt.Errorf("ServiceProfile %q has a route with an invalid condition: %w", serviceProfile.Name, err)
}
for _, rc := range route.ResponseClasses {
if rc == nil {
return fmt.Errorf("ServiceProfile %q has a null response class", serviceProfile.Name)
}
if rc.Condition == nil {
return fmt.Errorf("ServiceProfile %q has a response class with no condition", serviceProfile.Name)
}
Expand Down Expand Up @@ -119,6 +127,9 @@ func ValidateRequestMatch(reqMatch *sp.RequestMatch) error {
if reqMatch.All != nil {
matchKindSet = true
for _, child := range reqMatch.All {
if child == nil {
return errNilMatchAll
}
err := ValidateRequestMatch(child)
if err != nil {
return err
Expand All @@ -128,6 +139,9 @@ func ValidateRequestMatch(reqMatch *sp.RequestMatch) error {
if reqMatch.Any != nil {
matchKindSet = true
for _, child := range reqMatch.Any {
if child == nil {
return errNilMatchAny
}
err := ValidateRequestMatch(child)
if err != nil {
return err
Expand Down Expand Up @@ -162,6 +176,9 @@ func ValidateResponseMatch(rspMatch *sp.ResponseMatch) error {
if rspMatch.All != nil {
matchKindSet = true
for _, child := range rspMatch.All {
if child == nil {
return errNilMatchAll
}
err := ValidateResponseMatch(child)
if err != nil {
return err
Expand All @@ -171,6 +188,9 @@ func ValidateResponseMatch(rspMatch *sp.ResponseMatch) error {
if rspMatch.Any != nil {
matchKindSet = true
for _, child := range rspMatch.Any {
if child == nil {
return errNilMatchAny
}
err := ValidateResponseMatch(child)
if err != nil {
return err
Expand Down
131 changes: 131 additions & 0 deletions pkg/profiles/profiles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,137 @@ spec:
method: GET
pathRegex: /route-1`,
},
{
err: errors.New(`ServiceProfile "name.ns.svc.cluster.local" has a null route`),
sp: `apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
name: name.ns.svc.cluster.local
namespace: linkerd-ns
spec:
routes:
-`,
},
{
err: errors.New(`ServiceProfile "name.ns.svc.cluster.local" has a route with an invalid condition: null condition "all"`),
sp: `apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
name: name.ns.svc.cluster.local
namespace: linkerd-ns
spec:
routes:
- name: name-1
condition:
method: GET
pathRegex: /route-1
all:
-`,
},
{
err: errors.New(`ServiceProfile "name.ns.svc.cluster.local" has a route with an invalid condition: null condition "any"`),
sp: `apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
name: name.ns.svc.cluster.local
namespace: linkerd-ns
spec:
routes:
- name: name-1
condition:
method: GET
pathRegex: /route-1
any:
-`,
},
{
err: errors.New(`ServiceProfile "name.ns.svc.cluster.local" has a null response class`),
sp: `apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
name: name.ns.svc.cluster.local
namespace: linkerd-ns
spec:
routes:
- name: name-1
condition:
method: GET
pathRegex: /route-1
responseClasses:
-`,
},
{
err: errors.New(`ServiceProfile "name.ns.svc.cluster.local" has a response class with an invalid condition: null condition "all"`),
sp: `apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
name: name.ns.svc.cluster.local
namespace: linkerd-ns
spec:
routes:
- name: name-1
condition:
method: GET
pathRegex: /route-1
responseClasses:
- condition:
status:
min: 500
max: 599
all:
-`,
},
{
err: errors.New(`ServiceProfile "name.ns.svc.cluster.local" has a response class with an invalid condition: null condition "any"`),
sp: `apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
name: name.ns.svc.cluster.local
namespace: linkerd-ns
spec:
routes:
- name: name-1
condition:
method: GET
pathRegex: /route-1
responseClasses:
- condition:
status:
min: 500
max: 599
any:
-`,
},
{
err: nil,
sp: `apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
name: name.ns.svc.cluster.local
namespace: linkerd-ns
spec:
routes:
- name: name-1
condition:
method: GET
pathRegex: /route-1,
timeout: 1ns`,
},
{
err: errors.New(`ServiceProfile "name.ns.svc.cluster.local" has a route with an invalid timeout: time: invalid duration "one-second"`),
sp: `apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
name: name.ns.svc.cluster.local
namespace: linkerd-ns
spec:
routes:
- name: name-1
condition:
method: GET
pathRegex: /route-1,
timeout: one-second`,
},
}

for id, exp := range expectations {
Expand Down