Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(kuma-cp): allow using Dataplane kind in top level targetRef in all policies #12659

Merged
merged 14 commits into from
Jan 31, 2025
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ var DoNothingResourceResourceTypeDescriptor = model.ResourceTypeDescriptor{
IsTargetRefBased: false,
HasToTargetRef: false,
HasFromTargetRef: false,
HasRulesTargetRef: false,
HasStatus: false,
AllowedOnSystemNamespaceOnly: false,
IsReferenceableInTo: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ var HostnameGeneratorResourceTypeDescriptor = model.ResourceTypeDescriptor{
IsTargetRefBased: false,
HasToTargetRef: false,
HasFromTargetRef: false,
HasRulesTargetRef: false,
HasStatus: false,
AllowedOnSystemNamespaceOnly: true,
IsReferenceableInTo: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ var MeshExternalServiceResourceTypeDescriptor = model.ResourceTypeDescriptor{
IsTargetRefBased: false,
HasToTargetRef: false,
HasFromTargetRef: false,
HasRulesTargetRef: false,
HasStatus: true,
AllowedOnSystemNamespaceOnly: true,
IsReferenceableInTo: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ var MeshMultiZoneServiceResourceTypeDescriptor = model.ResourceTypeDescriptor{
IsTargetRefBased: false,
HasToTargetRef: false,
HasFromTargetRef: false,
HasRulesTargetRef: false,
HasStatus: true,
AllowedOnSystemNamespaceOnly: false,
IsReferenceableInTo: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ var MeshServiceResourceTypeDescriptor = model.ResourceTypeDescriptor{
IsTargetRefBased: false,
HasToTargetRef: false,
HasFromTargetRef: false,
HasRulesTargetRef: false,
HasStatus: true,
AllowedOnSystemNamespaceOnly: false,
IsReferenceableInTo: true,
Expand Down
4 changes: 3 additions & 1 deletion pkg/core/resources/model/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,10 @@ type ResourceTypeDescriptor struct {
IsTargetRefBased bool
// HasToTargetRef indicates that the policy can be applied to outbound traffic
HasToTargetRef bool
// HasFromTargetRef indicates that the policy can be applied to outbound traffic
// HasFromTargetRef indicates that the policy can be applied to inbound traffic
HasFromTargetRef bool
// HasRulesTargetRef indicates that the policy can be applied to inbound traffic
HasRulesTargetRef bool
// HasStatus indicates that the policy has a status field
HasStatus bool
// IsProxy indicates if this resource is a proxy
Expand Down
12 changes: 12 additions & 0 deletions pkg/plugins/policies/core/rules/inbound/inboundrules.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,15 @@ func buildRules[T interface {
Origin: ruleOrigin,
}}, nil
}

func AffectsInbounds(p core_model.Policy) bool {
pr, ok := p.(PolicyWithRules)
if ok && len(pr.GetRules()) > 0 {
return true
}
pf, ok := p.(core_model.PolicyWithFromList)
if ok && len(pf.GetFromList()) > 0 {
return true
}
return false
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ var DoNothingPolicyResourceTypeDescriptor = model.ResourceTypeDescriptor{
IsTargetRefBased: true,
HasToTargetRef: true,
HasFromTargetRef: true,
HasRulesTargetRef: false,
HasStatus: false,
AllowedOnSystemNamespaceOnly: false,
IsReferenceableInTo: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ import (
common_api "github.com/kumahq/kuma/api/common/v1alpha1"
"github.com/kumahq/kuma/pkg/core/resources/apis/mesh"
"github.com/kumahq/kuma/pkg/core/validators"
"github.com/kumahq/kuma/pkg/plugins/policies/core/rules/inbound"
)

func (r *MeshAccessLogResource) validate() error {
var verr validators.ValidationError
path := validators.RootedAt("spec")
verr.AddErrorAt(path.Field("targetRef"), validateTop(r.Spec.GetTargetRef()))
verr.AddErrorAt(path.Field("targetRef"), r.validateTop(r.Spec.GetTargetRef(), inbound.AffectsInbounds(r.Spec)))
if len(r.Spec.To) == 0 && len(r.Spec.From) == 0 {
verr.AddViolationAt(path, "at least one of 'from', 'to' has to be defined")
}
Expand All @@ -22,16 +23,18 @@ func (r *MeshAccessLogResource) validate() error {
return verr.OrNil()
}

func validateTop(targetRef common_api.TargetRef) validators.ValidationError {
func (r *MeshAccessLogResource) validateTop(targetRef common_api.TargetRef, isInboundPolicy bool) validators.ValidationError {
targetRefErr := mesh.ValidateTargetRef(targetRef, &mesh.ValidateTargetRefOpts{
SupportedKinds: []common_api.TargetRefKind{
common_api.Mesh,
common_api.MeshSubset,
common_api.MeshGateway,
common_api.MeshService,
common_api.MeshServiceSubset,
common_api.Dataplane,
},
GatewayListenerTagsAllowed: true,
IsInboundPolicy: isInboundPolicy,
})
return targetRefErr
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,22 @@ from:
violations:
- field: spec.from[0].default.backends
message: 'must be defined'`,
}),
Entry("sectionName with outbound policies", testCase{
inputYaml: `
targetRef:
kind: Dataplane
sectionName: test
to:
- targetRef:
kind: Mesh
`,
expected: `
violations:
- field: spec.targetRef.sectionName
message: can only be used with inbound policies
- field: spec.to[0].default.backends
message: must be defined`,
}),
Entry("'address' not valid", testCase{
inputYaml: `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ var MeshAccessLogResourceTypeDescriptor = model.ResourceTypeDescriptor{
IsTargetRefBased: true,
HasToTargetRef: true,
HasFromTargetRef: true,
HasRulesTargetRef: false,
HasStatus: false,
AllowedOnSystemNamespaceOnly: false,
IsReferenceableInTo: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import (
common_api "github.com/kumahq/kuma/api/common/v1alpha1"
"github.com/kumahq/kuma/pkg/core/resources/apis/mesh"
"github.com/kumahq/kuma/pkg/core/validators"
"github.com/kumahq/kuma/pkg/plugins/policies/core/rules/inbound"
"github.com/kumahq/kuma/pkg/util/pointer"
)

func (r *MeshCircuitBreakerResource) validate() error {
var verr validators.ValidationError
path := validators.RootedAt("spec")
verr.AddErrorAt(path.Field("targetRef"), validateTop(r.Spec.TargetRef))
verr.AddErrorAt(path.Field("targetRef"), r.validateTop(r.Spec.TargetRef, inbound.AffectsInbounds(r.Spec)))
if len(r.Spec.To) == 0 && len(r.Spec.From) == 0 {
verr.AddViolationAt(path, "at least one of 'from', 'to' has to be defined")
}
Expand All @@ -21,7 +22,7 @@ func (r *MeshCircuitBreakerResource) validate() error {
return verr.OrNil()
}

func validateTop(targetRef *common_api.TargetRef) validators.ValidationError {
func (r *MeshCircuitBreakerResource) validateTop(targetRef *common_api.TargetRef, isInboundPolicy bool) validators.ValidationError {
if targetRef == nil {
return validators.ValidationError{}
}
Expand All @@ -32,8 +33,10 @@ func validateTop(targetRef *common_api.TargetRef) validators.ValidationError {
common_api.MeshService,
common_api.MeshGateway,
common_api.MeshServiceSubset,
common_api.Dataplane,
},
GatewayListenerTagsAllowed: true,
IsInboundPolicy: isInboundPolicy,
})
return targetRefErr
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,23 @@ to:
violations:
- field: spec.to[0].targetRef.kind
message: value is not supported`,
}),
Entry("sectionName with outbound policy", testCase{
inputYaml: `
targetRef:
kind: Dataplane
sectionName: test
to:
- targetRef:
kind: MeshServiceSubset
default:
connectionLimits: { }`,
expected: `
violations:
- field: spec.targetRef.sectionName
message: can only be used with inbound policies
- field: spec.to[0].targetRef.kind
message: value is not supported`,
}),
Entry("missing configuration", testCase{
inputYaml: `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ var MeshCircuitBreakerResourceTypeDescriptor = model.ResourceTypeDescriptor{
IsTargetRefBased: true,
HasToTargetRef: true,
HasFromTargetRef: true,
HasRulesTargetRef: false,
HasStatus: false,
AllowedOnSystemNamespaceOnly: false,
IsReferenceableInTo: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,21 @@ import (
"github.com/kumahq/kuma/pkg/core/resources/apis/mesh"
core_model "github.com/kumahq/kuma/pkg/core/resources/model"
"github.com/kumahq/kuma/pkg/core/validators"
"github.com/kumahq/kuma/pkg/plugins/policies/core/rules/inbound"
"github.com/kumahq/kuma/pkg/util/pointer"
)

func (r *MeshFaultInjectionResource) validate() error {
var verr validators.ValidationError
path := validators.RootedAt("spec")
verr.AddErrorAt(path.Field("targetRef"), r.validateTop(r.Spec.TargetRef))
verr.AddErrorAt(path.Field("targetRef"), r.validateTop(r.Spec.TargetRef, inbound.AffectsInbounds(r.Spec)))
topLevel := pointer.DerefOr(r.Spec.TargetRef, common_api.TargetRef{Kind: common_api.Mesh})
verr.AddErrorAt(path, validateFrom(topLevel, r.Spec.From))
verr.AddErrorAt(path, validateTo(topLevel, r.Spec.To))
return verr.OrNil()
}

func (r *MeshFaultInjectionResource) validateTop(targetRef *common_api.TargetRef) validators.ValidationError {
func (r *MeshFaultInjectionResource) validateTop(targetRef *common_api.TargetRef, isInboundPolicy bool) validators.ValidationError {
if targetRef == nil {
return validators.ValidationError{}
}
Expand All @@ -32,8 +33,10 @@ func (r *MeshFaultInjectionResource) validateTop(targetRef *common_api.TargetRef
common_api.MeshGateway,
common_api.MeshService,
common_api.MeshServiceSubset,
common_api.Dataplane,
},
GatewayListenerTagsAllowed: true,
IsInboundPolicy: isInboundPolicy,
})
default:
return mesh.ValidateTargetRef(*targetRef, &mesh.ValidateTargetRefOpts{
Expand All @@ -42,7 +45,9 @@ func (r *MeshFaultInjectionResource) validateTop(targetRef *common_api.TargetRef
common_api.MeshSubset,
common_api.MeshService,
common_api.MeshServiceSubset,
common_api.Dataplane,
},
IsInboundPolicy: isInboundPolicy,
})
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,34 @@ from:
- delay: {}
- responseBandwidth:
limit: 1000
`),
ErrorCases("sectionName with outbound policy",
[]validators.Violation{
{
Field: "spec.targetRef.sectionName",
Message: "can only be used with inbound policies",
},
{
Field: "spec.to",
Message: "must not be defined",
},
}, `
type: MeshFaultInjection
mesh: mesh-1
name: fi1
targetRef:
kind: Dataplane
sectionName: test
to:
- targetRef:
kind: MeshService
name: web-backend
default:
http:
- abort: {}
- delay: {}
- responseBandwidth:
limit: 1000
`),
ErrorCases("incorrect value in percentage",
[]validators.Violation{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ var MeshFaultInjectionResourceTypeDescriptor = model.ResourceTypeDescriptor{
IsTargetRefBased: true,
HasToTargetRef: true,
HasFromTargetRef: true,
HasRulesTargetRef: false,
HasStatus: false,
AllowedOnSystemNamespaceOnly: false,
IsReferenceableInTo: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import (
func (r *MeshHealthCheckResource) validate() error {
var verr validators.ValidationError
path := validators.RootedAt("spec")
verr.AddErrorAt(path.Field("targetRef"), validateTop(r.Spec.TargetRef))
verr.AddErrorAt(path.Field("targetRef"), r.validateTop(r.Spec.TargetRef))
verr.AddErrorAt(path, validateTo(pointer.DerefOr(r.Spec.TargetRef, common_api.TargetRef{Kind: common_api.Mesh}), r.Spec.To))
return verr.OrNil()
}

func validateTop(targetRef *common_api.TargetRef) validators.ValidationError {
func (r *MeshHealthCheckResource) validateTop(targetRef *common_api.TargetRef) validators.ValidationError {
if targetRef == nil {
return validators.ValidationError{}
}
Expand All @@ -26,6 +26,7 @@ func validateTop(targetRef *common_api.TargetRef) validators.ValidationError {
common_api.MeshGateway,
common_api.MeshService,
common_api.MeshServiceSubset,
common_api.Dataplane,
},
GatewayListenerTagsAllowed: true,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ var MeshHealthCheckResourceTypeDescriptor = model.ResourceTypeDescriptor{
IsTargetRefBased: true,
HasToTargetRef: true,
HasFromTargetRef: false,
HasRulesTargetRef: false,
HasStatus: false,
AllowedOnSystemNamespaceOnly: false,
IsReferenceableInTo: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func (r *MeshHTTPRouteResource) validateTop(targetRef *common_api.TargetRef) val
common_api.MeshSubset,
common_api.MeshService,
common_api.MeshServiceSubset,
common_api.Dataplane,
},
GatewayListenerTagsAllowed: true,
})
Expand All @@ -48,6 +49,7 @@ func (r *MeshHTTPRouteResource) validateTop(targetRef *common_api.TargetRef) val
common_api.MeshSubset,
common_api.MeshService,
common_api.MeshServiceSubset,
common_api.Dataplane,
},
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ var MeshHTTPRouteResourceTypeDescriptor = model.ResourceTypeDescriptor{
IsTargetRefBased: true,
HasToTargetRef: true,
HasFromTargetRef: false,
HasRulesTargetRef: false,
HasStatus: false,
AllowedOnSystemNamespaceOnly: false,
IsReferenceableInTo: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
func (r *MeshLoadBalancingStrategyResource) validate() error {
var verr validators.ValidationError
path := validators.RootedAt("spec")
verr.AddErrorAt(path.Field("targetRef"), validateTop(r.Spec.TargetRef))
verr.AddErrorAt(path.Field("targetRef"), r.validateTop(r.Spec.TargetRef))
if len(r.Spec.To) == 0 {
verr.AddViolationAt(path.Field("to"), "needs at least one item")
}
Expand All @@ -22,7 +22,7 @@ func (r *MeshLoadBalancingStrategyResource) validate() error {
return verr.OrNil()
}

func validateTop(targetRef *common_api.TargetRef) validators.ValidationError {
func (r *MeshLoadBalancingStrategyResource) validateTop(targetRef *common_api.TargetRef) validators.ValidationError {
if targetRef == nil {
return validators.ValidationError{}
}
Expand All @@ -33,6 +33,7 @@ func validateTop(targetRef *common_api.TargetRef) validators.ValidationError {
common_api.MeshGateway,
common_api.MeshService,
common_api.MeshServiceSubset,
common_api.Dataplane,
},
GatewayListenerTagsAllowed: true,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ var MeshLoadBalancingStrategyResourceTypeDescriptor = model.ResourceTypeDescript
IsTargetRefBased: true,
HasToTargetRef: true,
HasFromTargetRef: false,
HasRulesTargetRef: false,
HasStatus: false,
AllowedOnSystemNamespaceOnly: false,
IsReferenceableInTo: false,
Expand Down
Loading
Loading