From d7ec0a2b1ac19208fb7dd9726309e3cf8cdc5848 Mon Sep 17 00:00:00 2001 From: Marcin Skalski Date: Fri, 31 Jan 2025 10:53:55 +0100 Subject: [PATCH] feat(kuma-cp): allow using Dataplane kind in top level targetRef in all policies (#12659) ## Motivation As in pr title, we want to use top level targetRef kind Dataplane in all policies --------- Signed-off-by: Marcin Skalski --- .../api/v1alpha1/zz_generated.resource.go | 1 + .../api/v1alpha1/zz_generated.resource.go | 1 + .../api/v1alpha1/zz_generated.resource.go | 1 + .../api/v1alpha1/zz_generated.resource.go | 1 + .../api/v1alpha1/zz_generated.resource.go | 1 + pkg/core/resources/model/resource.go | 4 ++- .../core/rules/inbound/inboundrules.go | 12 ++++++++ .../api/v1alpha1/zz_generated.resource.go | 1 + .../meshaccesslog/api/v1alpha1/validator.go | 7 +++-- .../api/v1alpha1/validator_test.go | 16 +++++++++++ .../api/v1alpha1/zz_generated.resource.go | 1 + .../api/v1alpha1/validator.go | 7 +++-- .../api/v1alpha1/validator_test.go | 17 +++++++++++ .../api/v1alpha1/zz_generated.resource.go | 1 + .../api/v1alpha1/validator.go | 9 ++++-- .../api/v1alpha1/validator_test.go | 28 +++++++++++++++++++ .../api/v1alpha1/zz_generated.resource.go | 1 + .../meshhealthcheck/api/v1alpha1/validator.go | 5 ++-- .../api/v1alpha1/zz_generated.resource.go | 1 + .../meshhttproute/api/v1alpha1/validation.go | 2 ++ .../api/v1alpha1/zz_generated.resource.go | 1 + .../api/v1alpha1/validator.go | 5 ++-- .../api/v1alpha1/zz_generated.resource.go | 1 + .../meshmetric/api/v1alpha1/validator.go | 2 ++ .../api/v1alpha1/zz_generated.resource.go | 1 + .../meshpassthrough/api/v1alpha1/validator.go | 5 ++-- .../api/v1alpha1/zz_generated.resource.go | 1 + .../meshproxypatch/api/v1alpha1/validator.go | 2 ++ .../api/v1alpha1/zz_generated.resource.go | 1 + .../meshratelimit/api/v1alpha1/validator.go | 9 ++++-- .../api/v1alpha1/validator_test.go | 16 +++++++++++ .../api/v1alpha1/zz_generated.resource.go | 1 + .../meshretry/api/v1alpha1/validator.go | 2 ++ .../api/v1alpha1/zz_generated.resource.go | 1 + .../meshtcproute/api/v1alpha1/validator.go | 2 ++ .../api/v1alpha1/zz_generated.resource.go | 1 + .../meshtimeout/api/v1alpha1/validator.go | 8 ++++-- .../api/v1alpha1/validator_test.go | 18 ++++++++++++ .../api/v1alpha1/zz_generated.resource.go | 1 + .../invalid-top-level-sectionName.input.yaml | 6 ++++ .../invalid-top-level-sectionName.output.yaml | 3 ++ .../meshtls/api/v1alpha1/validator.go | 7 +++-- .../meshtls/api/v1alpha1/validator_test.go | 4 +++ .../api/v1alpha1/zz_generated.resource.go | 1 + .../meshtrace/api/v1alpha1/validator.go | 2 ++ .../api/v1alpha1/zz_generated.resource.go | 1 + .../api/v1alpha1/validator.go | 7 +++-- .../api/v1alpha1/validator_test.go | 14 ++++++++++ .../api/v1alpha1/zz_generated.resource.go | 1 + .../policy-gen/generator/cmd/core_resource.go | 1 + 50 files changed, 219 insertions(+), 23 deletions(-) create mode 100644 pkg/plugins/policies/meshtls/api/v1alpha1/testdata/invalid-top-level-sectionName.input.yaml create mode 100644 pkg/plugins/policies/meshtls/api/v1alpha1/testdata/invalid-top-level-sectionName.output.yaml diff --git a/pkg/core/resources/apis/donothingresource/api/v1alpha1/zz_generated.resource.go b/pkg/core/resources/apis/donothingresource/api/v1alpha1/zz_generated.resource.go index 212ab5fd5128..9bccff415eda 100644 --- a/pkg/core/resources/apis/donothingresource/api/v1alpha1/zz_generated.resource.go +++ b/pkg/core/resources/apis/donothingresource/api/v1alpha1/zz_generated.resource.go @@ -149,6 +149,7 @@ var DoNothingResourceResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: false, HasToTargetRef: false, HasFromTargetRef: false, + HasRulesTargetRef: false, HasStatus: false, AllowedOnSystemNamespaceOnly: false, IsReferenceableInTo: false, diff --git a/pkg/core/resources/apis/hostnamegenerator/api/v1alpha1/zz_generated.resource.go b/pkg/core/resources/apis/hostnamegenerator/api/v1alpha1/zz_generated.resource.go index 408802fbe73d..43ba87e119d3 100644 --- a/pkg/core/resources/apis/hostnamegenerator/api/v1alpha1/zz_generated.resource.go +++ b/pkg/core/resources/apis/hostnamegenerator/api/v1alpha1/zz_generated.resource.go @@ -150,6 +150,7 @@ var HostnameGeneratorResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: false, HasToTargetRef: false, HasFromTargetRef: false, + HasRulesTargetRef: false, HasStatus: false, AllowedOnSystemNamespaceOnly: true, IsReferenceableInTo: false, diff --git a/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/zz_generated.resource.go b/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/zz_generated.resource.go index 709a81730645..8378cde989b4 100644 --- a/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/zz_generated.resource.go +++ b/pkg/core/resources/apis/meshexternalservice/api/v1alpha1/zz_generated.resource.go @@ -161,6 +161,7 @@ var MeshExternalServiceResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: false, HasToTargetRef: false, HasFromTargetRef: false, + HasRulesTargetRef: false, HasStatus: true, AllowedOnSystemNamespaceOnly: true, IsReferenceableInTo: true, diff --git a/pkg/core/resources/apis/meshmultizoneservice/api/v1alpha1/zz_generated.resource.go b/pkg/core/resources/apis/meshmultizoneservice/api/v1alpha1/zz_generated.resource.go index 3abf1903f938..362d21455fcd 100644 --- a/pkg/core/resources/apis/meshmultizoneservice/api/v1alpha1/zz_generated.resource.go +++ b/pkg/core/resources/apis/meshmultizoneservice/api/v1alpha1/zz_generated.resource.go @@ -161,6 +161,7 @@ var MeshMultiZoneServiceResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: false, HasToTargetRef: false, HasFromTargetRef: false, + HasRulesTargetRef: false, HasStatus: true, AllowedOnSystemNamespaceOnly: false, IsReferenceableInTo: true, diff --git a/pkg/core/resources/apis/meshservice/api/v1alpha1/zz_generated.resource.go b/pkg/core/resources/apis/meshservice/api/v1alpha1/zz_generated.resource.go index 0acc941e9872..b4aacbb5f3f7 100644 --- a/pkg/core/resources/apis/meshservice/api/v1alpha1/zz_generated.resource.go +++ b/pkg/core/resources/apis/meshservice/api/v1alpha1/zz_generated.resource.go @@ -161,6 +161,7 @@ var MeshServiceResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: false, HasToTargetRef: false, HasFromTargetRef: false, + HasRulesTargetRef: false, HasStatus: true, AllowedOnSystemNamespaceOnly: false, IsReferenceableInTo: true, diff --git a/pkg/core/resources/model/resource.go b/pkg/core/resources/model/resource.go index cf3197d3389c..5d1b2b90fa1e 100644 --- a/pkg/core/resources/model/resource.go +++ b/pkg/core/resources/model/resource.go @@ -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 diff --git a/pkg/plugins/policies/core/rules/inbound/inboundrules.go b/pkg/plugins/policies/core/rules/inbound/inboundrules.go index c71f2f01530c..429cacf426f3 100644 --- a/pkg/plugins/policies/core/rules/inbound/inboundrules.go +++ b/pkg/plugins/policies/core/rules/inbound/inboundrules.go @@ -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 +} diff --git a/pkg/plugins/policies/donothingpolicy/api/v1alpha1/zz_generated.resource.go b/pkg/plugins/policies/donothingpolicy/api/v1alpha1/zz_generated.resource.go index b5ee5b92decb..8d6953bcf436 100644 --- a/pkg/plugins/policies/donothingpolicy/api/v1alpha1/zz_generated.resource.go +++ b/pkg/plugins/policies/donothingpolicy/api/v1alpha1/zz_generated.resource.go @@ -149,6 +149,7 @@ var DoNothingPolicyResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: true, HasToTargetRef: true, HasFromTargetRef: true, + HasRulesTargetRef: false, HasStatus: false, AllowedOnSystemNamespaceOnly: false, IsReferenceableInTo: false, diff --git a/pkg/plugins/policies/meshaccesslog/api/v1alpha1/validator.go b/pkg/plugins/policies/meshaccesslog/api/v1alpha1/validator.go index 520e559bebd4..9d14a5a3b29e 100644 --- a/pkg/plugins/policies/meshaccesslog/api/v1alpha1/validator.go +++ b/pkg/plugins/policies/meshaccesslog/api/v1alpha1/validator.go @@ -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") } @@ -22,7 +23,7 @@ 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, @@ -30,8 +31,10 @@ func validateTop(targetRef common_api.TargetRef) validators.ValidationError { common_api.MeshGateway, common_api.MeshService, common_api.MeshServiceSubset, + common_api.Dataplane, }, GatewayListenerTagsAllowed: true, + IsInboundPolicy: isInboundPolicy, }) return targetRefErr } diff --git a/pkg/plugins/policies/meshaccesslog/api/v1alpha1/validator_test.go b/pkg/plugins/policies/meshaccesslog/api/v1alpha1/validator_test.go index 4e775bb5dd53..6fba810214f6 100644 --- a/pkg/plugins/policies/meshaccesslog/api/v1alpha1/validator_test.go +++ b/pkg/plugins/policies/meshaccesslog/api/v1alpha1/validator_test.go @@ -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: ` diff --git a/pkg/plugins/policies/meshaccesslog/api/v1alpha1/zz_generated.resource.go b/pkg/plugins/policies/meshaccesslog/api/v1alpha1/zz_generated.resource.go index 5c0187dea472..ff6e3bb22ed9 100644 --- a/pkg/plugins/policies/meshaccesslog/api/v1alpha1/zz_generated.resource.go +++ b/pkg/plugins/policies/meshaccesslog/api/v1alpha1/zz_generated.resource.go @@ -150,6 +150,7 @@ var MeshAccessLogResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: true, HasToTargetRef: true, HasFromTargetRef: true, + HasRulesTargetRef: false, HasStatus: false, AllowedOnSystemNamespaceOnly: false, IsReferenceableInTo: false, diff --git a/pkg/plugins/policies/meshcircuitbreaker/api/v1alpha1/validator.go b/pkg/plugins/policies/meshcircuitbreaker/api/v1alpha1/validator.go index 6abafb840f51..b6ca9d8e21f7 100644 --- a/pkg/plugins/policies/meshcircuitbreaker/api/v1alpha1/validator.go +++ b/pkg/plugins/policies/meshcircuitbreaker/api/v1alpha1/validator.go @@ -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") } @@ -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{} } @@ -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 } diff --git a/pkg/plugins/policies/meshcircuitbreaker/api/v1alpha1/validator_test.go b/pkg/plugins/policies/meshcircuitbreaker/api/v1alpha1/validator_test.go index f2a5cb1eb702..bba9948eed34 100644 --- a/pkg/plugins/policies/meshcircuitbreaker/api/v1alpha1/validator_test.go +++ b/pkg/plugins/policies/meshcircuitbreaker/api/v1alpha1/validator_test.go @@ -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: ` diff --git a/pkg/plugins/policies/meshcircuitbreaker/api/v1alpha1/zz_generated.resource.go b/pkg/plugins/policies/meshcircuitbreaker/api/v1alpha1/zz_generated.resource.go index 9ba0ff9e5ac4..3b4dc3b88f12 100644 --- a/pkg/plugins/policies/meshcircuitbreaker/api/v1alpha1/zz_generated.resource.go +++ b/pkg/plugins/policies/meshcircuitbreaker/api/v1alpha1/zz_generated.resource.go @@ -150,6 +150,7 @@ var MeshCircuitBreakerResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: true, HasToTargetRef: true, HasFromTargetRef: true, + HasRulesTargetRef: false, HasStatus: false, AllowedOnSystemNamespaceOnly: false, IsReferenceableInTo: false, diff --git a/pkg/plugins/policies/meshfaultinjection/api/v1alpha1/validator.go b/pkg/plugins/policies/meshfaultinjection/api/v1alpha1/validator.go index 4af2feac0f14..c9c58911220f 100644 --- a/pkg/plugins/policies/meshfaultinjection/api/v1alpha1/validator.go +++ b/pkg/plugins/policies/meshfaultinjection/api/v1alpha1/validator.go @@ -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{} } @@ -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{ @@ -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, }) } } diff --git a/pkg/plugins/policies/meshfaultinjection/api/v1alpha1/validator_test.go b/pkg/plugins/policies/meshfaultinjection/api/v1alpha1/validator_test.go index 74df9c835def..a9d531ebcdd8 100644 --- a/pkg/plugins/policies/meshfaultinjection/api/v1alpha1/validator_test.go +++ b/pkg/plugins/policies/meshfaultinjection/api/v1alpha1/validator_test.go @@ -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{ diff --git a/pkg/plugins/policies/meshfaultinjection/api/v1alpha1/zz_generated.resource.go b/pkg/plugins/policies/meshfaultinjection/api/v1alpha1/zz_generated.resource.go index 14b40bfa3ec6..1087d22d4e2d 100644 --- a/pkg/plugins/policies/meshfaultinjection/api/v1alpha1/zz_generated.resource.go +++ b/pkg/plugins/policies/meshfaultinjection/api/v1alpha1/zz_generated.resource.go @@ -150,6 +150,7 @@ var MeshFaultInjectionResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: true, HasToTargetRef: true, HasFromTargetRef: true, + HasRulesTargetRef: false, HasStatus: false, AllowedOnSystemNamespaceOnly: false, IsReferenceableInTo: false, diff --git a/pkg/plugins/policies/meshhealthcheck/api/v1alpha1/validator.go b/pkg/plugins/policies/meshhealthcheck/api/v1alpha1/validator.go index ba1eb0be209d..ab3fa670db38 100644 --- a/pkg/plugins/policies/meshhealthcheck/api/v1alpha1/validator.go +++ b/pkg/plugins/policies/meshhealthcheck/api/v1alpha1/validator.go @@ -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{} } @@ -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, }) diff --git a/pkg/plugins/policies/meshhealthcheck/api/v1alpha1/zz_generated.resource.go b/pkg/plugins/policies/meshhealthcheck/api/v1alpha1/zz_generated.resource.go index b806de95a1c0..62c074bd330a 100644 --- a/pkg/plugins/policies/meshhealthcheck/api/v1alpha1/zz_generated.resource.go +++ b/pkg/plugins/policies/meshhealthcheck/api/v1alpha1/zz_generated.resource.go @@ -150,6 +150,7 @@ var MeshHealthCheckResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: true, HasToTargetRef: true, HasFromTargetRef: false, + HasRulesTargetRef: false, HasStatus: false, AllowedOnSystemNamespaceOnly: false, IsReferenceableInTo: false, diff --git a/pkg/plugins/policies/meshhttproute/api/v1alpha1/validation.go b/pkg/plugins/policies/meshhttproute/api/v1alpha1/validation.go index 4adeb86979e8..1691605880d4 100644 --- a/pkg/plugins/policies/meshhttproute/api/v1alpha1/validation.go +++ b/pkg/plugins/policies/meshhttproute/api/v1alpha1/validation.go @@ -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, }) @@ -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, }, }) } diff --git a/pkg/plugins/policies/meshhttproute/api/v1alpha1/zz_generated.resource.go b/pkg/plugins/policies/meshhttproute/api/v1alpha1/zz_generated.resource.go index 8f227048d37d..a6aac286968d 100644 --- a/pkg/plugins/policies/meshhttproute/api/v1alpha1/zz_generated.resource.go +++ b/pkg/plugins/policies/meshhttproute/api/v1alpha1/zz_generated.resource.go @@ -150,6 +150,7 @@ var MeshHTTPRouteResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: true, HasToTargetRef: true, HasFromTargetRef: false, + HasRulesTargetRef: false, HasStatus: false, AllowedOnSystemNamespaceOnly: false, IsReferenceableInTo: false, diff --git a/pkg/plugins/policies/meshloadbalancingstrategy/api/v1alpha1/validator.go b/pkg/plugins/policies/meshloadbalancingstrategy/api/v1alpha1/validator.go index 87f2ce8da4ec..c2655b1e76da 100644 --- a/pkg/plugins/policies/meshloadbalancingstrategy/api/v1alpha1/validator.go +++ b/pkg/plugins/policies/meshloadbalancingstrategy/api/v1alpha1/validator.go @@ -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") } @@ -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{} } @@ -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, }) diff --git a/pkg/plugins/policies/meshloadbalancingstrategy/api/v1alpha1/zz_generated.resource.go b/pkg/plugins/policies/meshloadbalancingstrategy/api/v1alpha1/zz_generated.resource.go index fde97fc07996..980462c27bcd 100644 --- a/pkg/plugins/policies/meshloadbalancingstrategy/api/v1alpha1/zz_generated.resource.go +++ b/pkg/plugins/policies/meshloadbalancingstrategy/api/v1alpha1/zz_generated.resource.go @@ -150,6 +150,7 @@ var MeshLoadBalancingStrategyResourceTypeDescriptor = model.ResourceTypeDescript IsTargetRefBased: true, HasToTargetRef: true, HasFromTargetRef: false, + HasRulesTargetRef: false, HasStatus: false, AllowedOnSystemNamespaceOnly: false, IsReferenceableInTo: false, diff --git a/pkg/plugins/policies/meshmetric/api/v1alpha1/validator.go b/pkg/plugins/policies/meshmetric/api/v1alpha1/validator.go index df0af8dd6559..8dfa5e52f8bf 100644 --- a/pkg/plugins/policies/meshmetric/api/v1alpha1/validator.go +++ b/pkg/plugins/policies/meshmetric/api/v1alpha1/validator.go @@ -35,6 +35,7 @@ func (r *MeshMetricResource) validateTop(targetRef *common_api.TargetRef) valida common_api.MeshService, common_api.MeshServiceSubset, common_api.MeshGateway, + common_api.Dataplane, }, GatewayListenerTagsAllowed: true, }) @@ -44,6 +45,7 @@ func (r *MeshMetricResource) validateTop(targetRef *common_api.TargetRef) valida common_api.Mesh, common_api.MeshSubset, common_api.MeshService, + common_api.Dataplane, common_api.MeshServiceSubset, }, }) diff --git a/pkg/plugins/policies/meshmetric/api/v1alpha1/zz_generated.resource.go b/pkg/plugins/policies/meshmetric/api/v1alpha1/zz_generated.resource.go index 5cf54320cacf..d90a446c3bc2 100644 --- a/pkg/plugins/policies/meshmetric/api/v1alpha1/zz_generated.resource.go +++ b/pkg/plugins/policies/meshmetric/api/v1alpha1/zz_generated.resource.go @@ -150,6 +150,7 @@ var MeshMetricResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: true, HasToTargetRef: false, HasFromTargetRef: false, + HasRulesTargetRef: false, HasStatus: false, AllowedOnSystemNamespaceOnly: false, IsReferenceableInTo: false, diff --git a/pkg/plugins/policies/meshpassthrough/api/v1alpha1/validator.go b/pkg/plugins/policies/meshpassthrough/api/v1alpha1/validator.go index 65df4b2434ba..6254ff0d1d21 100644 --- a/pkg/plugins/policies/meshpassthrough/api/v1alpha1/validator.go +++ b/pkg/plugins/policies/meshpassthrough/api/v1alpha1/validator.go @@ -24,12 +24,12 @@ var ( func (r *MeshPassthroughResource) 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.Field("default"), validateDefault(r.Spec.Default)) return verr.OrNil() } -func validateTop(targetRef *common_api.TargetRef) validators.ValidationError { +func (r *MeshPassthroughResource) validateTop(targetRef *common_api.TargetRef) validators.ValidationError { if targetRef == nil { return validators.ValidationError{} } @@ -37,6 +37,7 @@ func validateTop(targetRef *common_api.TargetRef) validators.ValidationError { SupportedKinds: []common_api.TargetRefKind{ common_api.Mesh, common_api.MeshSubset, + common_api.Dataplane, }, }) return targetRefErr diff --git a/pkg/plugins/policies/meshpassthrough/api/v1alpha1/zz_generated.resource.go b/pkg/plugins/policies/meshpassthrough/api/v1alpha1/zz_generated.resource.go index 45a03b7682aa..bbe63f01ff05 100644 --- a/pkg/plugins/policies/meshpassthrough/api/v1alpha1/zz_generated.resource.go +++ b/pkg/plugins/policies/meshpassthrough/api/v1alpha1/zz_generated.resource.go @@ -150,6 +150,7 @@ var MeshPassthroughResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: true, HasToTargetRef: false, HasFromTargetRef: false, + HasRulesTargetRef: false, HasStatus: false, AllowedOnSystemNamespaceOnly: false, IsReferenceableInTo: false, diff --git a/pkg/plugins/policies/meshproxypatch/api/v1alpha1/validator.go b/pkg/plugins/policies/meshproxypatch/api/v1alpha1/validator.go index 7f6eaa86afbd..c2f9d5af985f 100644 --- a/pkg/plugins/policies/meshproxypatch/api/v1alpha1/validator.go +++ b/pkg/plugins/policies/meshproxypatch/api/v1alpha1/validator.go @@ -44,6 +44,7 @@ func (r *MeshProxyPatchResource) validateTop(targetRef *common_api.TargetRef) va common_api.MeshService, common_api.MeshServiceSubset, common_api.MeshGateway, + common_api.Dataplane, }, GatewayListenerTagsAllowed: false, }) @@ -52,6 +53,7 @@ func (r *MeshProxyPatchResource) validateTop(targetRef *common_api.TargetRef) va SupportedKinds: []common_api.TargetRefKind{ common_api.Mesh, common_api.MeshSubset, + common_api.Dataplane, common_api.MeshService, common_api.MeshServiceSubset, }, diff --git a/pkg/plugins/policies/meshproxypatch/api/v1alpha1/zz_generated.resource.go b/pkg/plugins/policies/meshproxypatch/api/v1alpha1/zz_generated.resource.go index 4e173de6d013..00ee9461a51b 100644 --- a/pkg/plugins/policies/meshproxypatch/api/v1alpha1/zz_generated.resource.go +++ b/pkg/plugins/policies/meshproxypatch/api/v1alpha1/zz_generated.resource.go @@ -150,6 +150,7 @@ var MeshProxyPatchResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: true, HasToTargetRef: false, HasFromTargetRef: false, + HasRulesTargetRef: false, HasStatus: false, AllowedOnSystemNamespaceOnly: false, IsReferenceableInTo: false, diff --git a/pkg/plugins/policies/meshratelimit/api/v1alpha1/validator.go b/pkg/plugins/policies/meshratelimit/api/v1alpha1/validator.go index 1ce0e684cb26..63280ed805dc 100644 --- a/pkg/plugins/policies/meshratelimit/api/v1alpha1/validator.go +++ b/pkg/plugins/policies/meshratelimit/api/v1alpha1/validator.go @@ -8,20 +8,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 *MeshRateLimitResource) 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 *MeshRateLimitResource) validateTop(targetRef *common_api.TargetRef) validators.ValidationError { +func (r *MeshRateLimitResource) validateTop(targetRef *common_api.TargetRef, isInboundPolicy bool) validators.ValidationError { if targetRef == nil { return validators.ValidationError{} } @@ -35,8 +36,10 @@ func (r *MeshRateLimitResource) validateTop(targetRef *common_api.TargetRef) val common_api.MeshService, common_api.MeshServiceSubset, common_api.MeshHTTPRoute, + common_api.Dataplane, }, GatewayListenerTagsAllowed: true, + IsInboundPolicy: isInboundPolicy, }) default: return mesh.ValidateTargetRef(*targetRef, &mesh.ValidateTargetRefOpts{ @@ -45,7 +48,9 @@ func (r *MeshRateLimitResource) validateTop(targetRef *common_api.TargetRef) val common_api.MeshSubset, common_api.MeshService, common_api.MeshServiceSubset, + common_api.Dataplane, }, + IsInboundPolicy: isInboundPolicy, }) } } diff --git a/pkg/plugins/policies/meshratelimit/api/v1alpha1/validator_test.go b/pkg/plugins/policies/meshratelimit/api/v1alpha1/validator_test.go index 0d6be24a58aa..d9a275e5cb5d 100644 --- a/pkg/plugins/policies/meshratelimit/api/v1alpha1/validator_test.go +++ b/pkg/plugins/policies/meshratelimit/api/v1alpha1/validator_test.go @@ -293,6 +293,22 @@ from: violations: - field: spec.from[0].default.local message: must be defined`, + }), + Entry("sectionName with outbound policy", testCase{ + inputYaml: ` +targetRef: + kind: Dataplane + sectionName: test +to: +- targetRef: + kind: Mesh + default: {}`, + expected: ` +violations: + - field: spec.targetRef.sectionName + message: can only be used with inbound policies + - field: spec.to + message: must not be defined`, }), Entry("neither tcp or http defined", testCase{ inputYaml: ` diff --git a/pkg/plugins/policies/meshratelimit/api/v1alpha1/zz_generated.resource.go b/pkg/plugins/policies/meshratelimit/api/v1alpha1/zz_generated.resource.go index c4703f4b11e9..26b1fdf3d666 100644 --- a/pkg/plugins/policies/meshratelimit/api/v1alpha1/zz_generated.resource.go +++ b/pkg/plugins/policies/meshratelimit/api/v1alpha1/zz_generated.resource.go @@ -150,6 +150,7 @@ var MeshRateLimitResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: true, HasToTargetRef: true, HasFromTargetRef: true, + HasRulesTargetRef: false, HasStatus: false, AllowedOnSystemNamespaceOnly: false, IsReferenceableInTo: false, diff --git a/pkg/plugins/policies/meshretry/api/v1alpha1/validator.go b/pkg/plugins/policies/meshretry/api/v1alpha1/validator.go index 8bf0316ceec7..75c5fc66b5ec 100644 --- a/pkg/plugins/policies/meshretry/api/v1alpha1/validator.go +++ b/pkg/plugins/policies/meshretry/api/v1alpha1/validator.go @@ -38,6 +38,7 @@ func (r *MeshRetryResource) validateTop(targetRef *common_api.TargetRef) validat common_api.MeshService, common_api.MeshServiceSubset, common_api.MeshHTTPRoute, + common_api.Dataplane, }, GatewayListenerTagsAllowed: true, }) @@ -48,6 +49,7 @@ func (r *MeshRetryResource) validateTop(targetRef *common_api.TargetRef) validat common_api.MeshSubset, common_api.MeshService, common_api.MeshServiceSubset, + common_api.Dataplane, }, }) } diff --git a/pkg/plugins/policies/meshretry/api/v1alpha1/zz_generated.resource.go b/pkg/plugins/policies/meshretry/api/v1alpha1/zz_generated.resource.go index fc0fecc30793..f75300a111fe 100644 --- a/pkg/plugins/policies/meshretry/api/v1alpha1/zz_generated.resource.go +++ b/pkg/plugins/policies/meshretry/api/v1alpha1/zz_generated.resource.go @@ -150,6 +150,7 @@ var MeshRetryResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: true, HasToTargetRef: true, HasFromTargetRef: false, + HasRulesTargetRef: false, HasStatus: false, AllowedOnSystemNamespaceOnly: false, IsReferenceableInTo: false, diff --git a/pkg/plugins/policies/meshtcproute/api/v1alpha1/validator.go b/pkg/plugins/policies/meshtcproute/api/v1alpha1/validator.go index c3430413dbcd..3a6cd746a69e 100644 --- a/pkg/plugins/policies/meshtcproute/api/v1alpha1/validator.go +++ b/pkg/plugins/policies/meshtcproute/api/v1alpha1/validator.go @@ -33,6 +33,7 @@ func (r *MeshTCPRouteResource) validateTop(targetRef *common_api.TargetRef) vali common_api.MeshGateway, common_api.MeshService, common_api.MeshServiceSubset, + common_api.Dataplane, }, GatewayListenerTagsAllowed: true, }) @@ -43,6 +44,7 @@ func (r *MeshTCPRouteResource) validateTop(targetRef *common_api.TargetRef) vali common_api.MeshSubset, common_api.MeshService, common_api.MeshServiceSubset, + common_api.Dataplane, }, }) } diff --git a/pkg/plugins/policies/meshtcproute/api/v1alpha1/zz_generated.resource.go b/pkg/plugins/policies/meshtcproute/api/v1alpha1/zz_generated.resource.go index 2d05b35795d7..4d0167da1352 100644 --- a/pkg/plugins/policies/meshtcproute/api/v1alpha1/zz_generated.resource.go +++ b/pkg/plugins/policies/meshtcproute/api/v1alpha1/zz_generated.resource.go @@ -150,6 +150,7 @@ var MeshTCPRouteResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: true, HasToTargetRef: true, HasFromTargetRef: false, + HasRulesTargetRef: false, HasStatus: false, AllowedOnSystemNamespaceOnly: false, IsReferenceableInTo: false, diff --git a/pkg/plugins/policies/meshtimeout/api/v1alpha1/validator.go b/pkg/plugins/policies/meshtimeout/api/v1alpha1/validator.go index 077095b4d743..a5b3a9afdfcc 100644 --- a/pkg/plugins/policies/meshtimeout/api/v1alpha1/validator.go +++ b/pkg/plugins/policies/meshtimeout/api/v1alpha1/validator.go @@ -6,13 +6,14 @@ 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 *MeshTimeoutResource) 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))) if len(r.Spec.Rules) > 0 && (len(r.Spec.To) > 0 || len(r.Spec.From) > 0) { verr.AddViolationAt(path, "fields 'to' and 'from' must be empty when 'rules' is defined") } @@ -25,7 +26,7 @@ func (r *MeshTimeoutResource) validate() error { return verr.OrNil() } -func (r *MeshTimeoutResource) validateTop(targetRef *common_api.TargetRef) validators.ValidationError { +func (r *MeshTimeoutResource) validateTop(targetRef *common_api.TargetRef, isInboundPolicy bool) validators.ValidationError { if targetRef == nil { return validators.ValidationError{} } @@ -42,7 +43,7 @@ func (r *MeshTimeoutResource) validateTop(targetRef *common_api.TargetRef) valid common_api.MeshHTTPRoute, }, GatewayListenerTagsAllowed: true, - IsInboundPolicy: true, + IsInboundPolicy: isInboundPolicy, }) default: return mesh.ValidateTargetRef(*targetRef, &mesh.ValidateTargetRefOpts{ @@ -53,6 +54,7 @@ func (r *MeshTimeoutResource) validateTop(targetRef *common_api.TargetRef) valid common_api.MeshService, common_api.MeshServiceSubset, }, + IsInboundPolicy: isInboundPolicy, }) } } diff --git a/pkg/plugins/policies/meshtimeout/api/v1alpha1/validator_test.go b/pkg/plugins/policies/meshtimeout/api/v1alpha1/validator_test.go index 93a5312054c4..38dcff4d6d82 100644 --- a/pkg/plugins/policies/meshtimeout/api/v1alpha1/validator_test.go +++ b/pkg/plugins/policies/meshtimeout/api/v1alpha1/validator_test.go @@ -171,6 +171,24 @@ to: requestTimeout: 1s`, expected: ` 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: + http: + requestTimeout: 1s`, + 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`, }), diff --git a/pkg/plugins/policies/meshtimeout/api/v1alpha1/zz_generated.resource.go b/pkg/plugins/policies/meshtimeout/api/v1alpha1/zz_generated.resource.go index 629788a40d3d..90701f33b0a0 100644 --- a/pkg/plugins/policies/meshtimeout/api/v1alpha1/zz_generated.resource.go +++ b/pkg/plugins/policies/meshtimeout/api/v1alpha1/zz_generated.resource.go @@ -150,6 +150,7 @@ var MeshTimeoutResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: true, HasToTargetRef: true, HasFromTargetRef: true, + HasRulesTargetRef: true, HasStatus: false, AllowedOnSystemNamespaceOnly: false, IsReferenceableInTo: false, diff --git a/pkg/plugins/policies/meshtls/api/v1alpha1/testdata/invalid-top-level-sectionName.input.yaml b/pkg/plugins/policies/meshtls/api/v1alpha1/testdata/invalid-top-level-sectionName.input.yaml new file mode 100644 index 000000000000..1933816bbb95 --- /dev/null +++ b/pkg/plugins/policies/meshtls/api/v1alpha1/testdata/invalid-top-level-sectionName.input.yaml @@ -0,0 +1,6 @@ +targetRef: + kind: Dataplane + sectionName: test +to: + - targetRef: + kind: Mesh \ No newline at end of file diff --git a/pkg/plugins/policies/meshtls/api/v1alpha1/testdata/invalid-top-level-sectionName.output.yaml b/pkg/plugins/policies/meshtls/api/v1alpha1/testdata/invalid-top-level-sectionName.output.yaml new file mode 100644 index 000000000000..8b12654ca86f --- /dev/null +++ b/pkg/plugins/policies/meshtls/api/v1alpha1/testdata/invalid-top-level-sectionName.output.yaml @@ -0,0 +1,3 @@ +violations: + - field: spec.targetRef.sectionName + message: can only be used with inbound policies \ No newline at end of file diff --git a/pkg/plugins/policies/meshtls/api/v1alpha1/validator.go b/pkg/plugins/policies/meshtls/api/v1alpha1/validator.go index abb039fd04c7..6bd4cf0174de 100644 --- a/pkg/plugins/policies/meshtls/api/v1alpha1/validator.go +++ b/pkg/plugins/policies/meshtls/api/v1alpha1/validator.go @@ -7,19 +7,20 @@ import ( common_tls "github.com/kumahq/kuma/api/common/v1alpha1/tls" "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 *MeshTLSResource) 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))) topLevel := pointer.DerefOr(r.Spec.TargetRef, common_api.TargetRef{Kind: common_api.Mesh, UsesSyntacticSugar: true}) verr.AddErrorAt(path.Field("from"), validateFrom(r.Spec.From, topLevel.Kind)) return verr.OrNil() } -func validateTop(targetRef *common_api.TargetRef) validators.ValidationError { +func (r *MeshTLSResource) validateTop(targetRef *common_api.TargetRef, isInboundPolicy bool) validators.ValidationError { if targetRef == nil { return validators.ValidationError{} } @@ -27,7 +28,9 @@ func validateTop(targetRef *common_api.TargetRef) validators.ValidationError { SupportedKinds: []common_api.TargetRefKind{ common_api.Mesh, common_api.MeshSubset, + common_api.Dataplane, }, + IsInboundPolicy: isInboundPolicy, }) return targetRefErr } diff --git a/pkg/plugins/policies/meshtls/api/v1alpha1/validator_test.go b/pkg/plugins/policies/meshtls/api/v1alpha1/validator_test.go index 53b871a882f0..f1d6401429b7 100644 --- a/pkg/plugins/policies/meshtls/api/v1alpha1/validator_test.go +++ b/pkg/plugins/policies/meshtls/api/v1alpha1/validator_test.go @@ -64,6 +64,10 @@ var _ = Describe("MeshTLS", func() { name: "meshtls-4", file: "full-valid-no-top-target", }), + Entry("sectionName without from or rules", testCase{ + name: "meshtls-5", + file: "invalid-top-level-sectionName", + }), ) }) }) diff --git a/pkg/plugins/policies/meshtls/api/v1alpha1/zz_generated.resource.go b/pkg/plugins/policies/meshtls/api/v1alpha1/zz_generated.resource.go index efa9811b3859..9ee3af0bc845 100644 --- a/pkg/plugins/policies/meshtls/api/v1alpha1/zz_generated.resource.go +++ b/pkg/plugins/policies/meshtls/api/v1alpha1/zz_generated.resource.go @@ -150,6 +150,7 @@ var MeshTLSResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: true, HasToTargetRef: false, HasFromTargetRef: true, + HasRulesTargetRef: false, HasStatus: false, AllowedOnSystemNamespaceOnly: false, IsReferenceableInTo: false, diff --git a/pkg/plugins/policies/meshtrace/api/v1alpha1/validator.go b/pkg/plugins/policies/meshtrace/api/v1alpha1/validator.go index 5b178b6ca39a..7eb5b3f1f14e 100644 --- a/pkg/plugins/policies/meshtrace/api/v1alpha1/validator.go +++ b/pkg/plugins/policies/meshtrace/api/v1alpha1/validator.go @@ -39,6 +39,7 @@ func (r *MeshTraceResource) validateTop(targetRef *common_api.TargetRef) validat common_api.MeshGateway, common_api.MeshService, common_api.MeshServiceSubset, + common_api.Dataplane, }, GatewayListenerTagsAllowed: false, }) @@ -49,6 +50,7 @@ func (r *MeshTraceResource) validateTop(targetRef *common_api.TargetRef) validat common_api.MeshSubset, common_api.MeshService, common_api.MeshServiceSubset, + common_api.Dataplane, }, }) } diff --git a/pkg/plugins/policies/meshtrace/api/v1alpha1/zz_generated.resource.go b/pkg/plugins/policies/meshtrace/api/v1alpha1/zz_generated.resource.go index 9deecc0acffe..6ec9e6cac692 100644 --- a/pkg/plugins/policies/meshtrace/api/v1alpha1/zz_generated.resource.go +++ b/pkg/plugins/policies/meshtrace/api/v1alpha1/zz_generated.resource.go @@ -150,6 +150,7 @@ var MeshTraceResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: true, HasToTargetRef: false, HasFromTargetRef: false, + HasRulesTargetRef: false, HasStatus: false, AllowedOnSystemNamespaceOnly: false, IsReferenceableInTo: false, diff --git a/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/validator.go b/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/validator.go index fea57012a246..92bbad2c9002 100644 --- a/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/validator.go +++ b/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/validator.go @@ -4,12 +4,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 *MeshTrafficPermissionResource) 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.From) == 0 { verr.AddViolationAt(path.Field("from"), "needs at least one item") } @@ -17,7 +18,7 @@ func (r *MeshTrafficPermissionResource) validate() error { return verr.OrNil() } -func validateTop(targetRef *common_api.TargetRef) validators.ValidationError { +func (r *MeshTrafficPermissionResource) validateTop(targetRef *common_api.TargetRef, isInboundPolicy bool) validators.ValidationError { if targetRef == nil { return validators.ValidationError{} } @@ -29,7 +30,7 @@ func validateTop(targetRef *common_api.TargetRef) validators.ValidationError { common_api.MeshServiceSubset, common_api.Dataplane, }, - IsInboundPolicy: true, + IsInboundPolicy: isInboundPolicy, }) return targetRefErr } diff --git a/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/validator_test.go b/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/validator_test.go index 2e43a22e3e25..d6532c35bad1 100644 --- a/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/validator_test.go +++ b/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/validator_test.go @@ -132,6 +132,20 @@ from: [] violations: - field: spec.from message: needs at least one item`, + }), + Entry("sectionName without from or rules", testCase{ + inputYaml: ` +targetRef: + kind: Dataplane + sectionName: test +to: [] +`, + expected: ` +violations: +- field: spec.targetRef.sectionName + message: can only be used with inbound policies +- field: spec.from + message: needs at least one item`, }), Entry("not supported kinds in 'from' array", testCase{ inputYaml: ` diff --git a/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/zz_generated.resource.go b/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/zz_generated.resource.go index 4611ca355fea..679bfd697639 100644 --- a/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/zz_generated.resource.go +++ b/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/zz_generated.resource.go @@ -150,6 +150,7 @@ var MeshTrafficPermissionResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: true, HasToTargetRef: false, HasFromTargetRef: true, + HasRulesTargetRef: false, HasStatus: false, AllowedOnSystemNamespaceOnly: false, IsReferenceableInTo: false, diff --git a/tools/policy-gen/generator/cmd/core_resource.go b/tools/policy-gen/generator/cmd/core_resource.go index 14a9dc075e34..75d8d0c29c39 100644 --- a/tools/policy-gen/generator/cmd/core_resource.go +++ b/tools/policy-gen/generator/cmd/core_resource.go @@ -220,6 +220,7 @@ var {{.Name}}ResourceTypeDescriptor = model.ResourceTypeDescriptor{ IsTargetRefBased: {{.IsPolicy}}, HasToTargetRef: {{.HasTo}}, HasFromTargetRef: {{.HasFrom}}, + HasRulesTargetRef: {{.HasRules}}, HasStatus: {{.HasStatus}}, AllowedOnSystemNamespaceOnly: {{.AllowedOnSystemNamespaceOnly}}, IsReferenceableInTo: {{.IsReferenceableInTo}},