diff --git a/mk/docs.mk b/mk/docs.mk index a9293e9704c3..4b82e907981c 100644 --- a/mk/docs.mk +++ b/mk/docs.mk @@ -18,7 +18,7 @@ docs/install/markdown: ## Generate CLI reference in markdown format .PHONY: docs/install/manpages docs/install/manpages: DESTDIR:=$(DESTDIR)/manpages docs/install/manpages: ## Generate CLI reference in man(1) format - @DESTDIR=$(DESTDIR) FORMAT=man $(GO_RUN) $(TOOLS_DIR)/tools/docs/generate.go + @DESTDIR=$(DESTDIR) FORMAT=man $(GO_RUN) $(TOOLS_DIR)/docs/generate.go .PHONY: docs/install/resources docs/install/resources: DESTDIR:=$(DESTDIR)/resources diff --git a/pkg/plugins/policies/donothingpolicy/api/v1alpha1/donothingpolicy.pb.go b/pkg/plugins/policies/donothingpolicy/api/v1alpha1/donothingpolicy.pb.go index 9ccbb4f6f933..a94524974891 100644 --- a/pkg/plugins/policies/donothingpolicy/api/v1alpha1/donothingpolicy.pb.go +++ b/pkg/plugins/policies/donothingpolicy/api/v1alpha1/donothingpolicy.pb.go @@ -272,7 +272,7 @@ var file_pkg_plugins_policies_donothingpolicy_api_v1alpha1_donothingpolicy_proto 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x72, 0x65, 0x66, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x6b, 0x75, 0x6d, 0x61, 0x2d, 0x64, 0x6f, 0x63, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x88, 0x05, 0x0a, 0x0f, 0x44, 0x6f, 0x4e, 0x6f, 0x74, 0x68, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa0, 0x05, 0x0a, 0x0f, 0x44, 0x6f, 0x4e, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x3d, 0x0a, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6b, 0x75, 0x6d, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, @@ -291,36 +291,38 @@ var file_pkg_plugins_policies_donothingpolicy_api_v1alpha1_donothingpolicy_proto 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x1a, 0x30, 0x0a, 0x04, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x28, 0x0a, 0x0f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x6f, 0x4e, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x44, - 0x6f, 0x4e, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x1a, 0xa3, 0x01, 0x0a, 0x02, 0x54, 0x6f, 0x12, - 0x3d, 0x0a, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, + 0x6f, 0x4e, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x1a, 0xaf, 0x01, 0x0a, 0x02, 0x54, 0x6f, 0x12, + 0x43, 0x0a, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6b, 0x75, 0x6d, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x52, 0x65, 0x66, 0x52, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x12, 0x5e, - 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x44, 0x2e, 0x6b, 0x75, 0x6d, 0x61, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2e, 0x70, - 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x64, 0x6f, 0x6e, 0x6f, 0x74, 0x68, 0x69, 0x6e, - 0x67, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x2e, 0x44, 0x6f, 0x4e, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x1a, 0xa5, - 0x01, 0x0a, 0x04, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x3d, 0x0a, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x52, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6b, 0x75, 0x6d, - 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x52, 0x09, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x12, 0x5e, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, - 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x6b, 0x75, 0x6d, 0x61, 0x2e, 0x70, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, - 0x64, 0x6f, 0x6e, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x6f, 0x4e, 0x6f, 0x74, 0x68, 0x69, - 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x52, 0x07, 0x64, - 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x08, 0xb2, 0x8c, 0x89, 0xa6, 0x01, 0x02, 0x08, 0x01, - 0x42, 0x74, 0x5a, 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, - 0x75, 0x6d, 0x61, 0x68, 0x71, 0x2f, 0x6b, 0x75, 0x6d, 0x61, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, - 0x64, 0x6f, 0x6e, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x8a, 0xb5, 0x18, 0x26, - 0x50, 0x01, 0xa2, 0x01, 0x0f, 0x44, 0x6f, 0x4e, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0xf2, 0x01, 0x0f, 0x64, 0x6f, 0x6e, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x65, 0x66, 0x42, 0x04, 0x88, 0xb5, 0x18, 0x01, 0x52, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x52, 0x65, 0x66, 0x12, 0x64, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x6b, 0x75, 0x6d, 0x61, 0x2e, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x64, 0x6f, + 0x6e, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x6f, 0x4e, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x42, 0x04, 0x88, 0xb5, 0x18, + 0x01, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x1a, 0xb1, 0x01, 0x0a, 0x04, 0x46, + 0x72, 0x6f, 0x6d, 0x12, 0x43, 0x0a, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6b, 0x75, 0x6d, 0x61, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x54, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x42, 0x04, 0x88, 0xb5, 0x18, 0x01, 0x52, 0x09, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x12, 0x64, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x6b, 0x75, 0x6d, 0x61, + 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, + 0x73, 0x2e, 0x64, 0x6f, 0x6e, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x6f, 0x4e, 0x6f, 0x74, + 0x68, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x42, + 0x04, 0x88, 0xb5, 0x18, 0x01, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x08, + 0xb2, 0x8c, 0x89, 0xa6, 0x01, 0x02, 0x08, 0x01, 0x42, 0x74, 0x5a, 0x48, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x75, 0x6d, 0x61, 0x68, 0x71, 0x2f, 0x6b, 0x75, + 0x6d, 0x61, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2f, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x64, 0x6f, 0x6e, 0x6f, 0x74, 0x68, 0x69, 0x6e, + 0x67, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x8a, 0xb5, 0x18, 0x26, 0x50, 0x01, 0xa2, 0x01, 0x0f, 0x44, 0x6f, 0x4e, + 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0xf2, 0x01, 0x0f, 0x64, + 0x6f, 0x6e, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/pkg/plugins/policies/donothingpolicy/api/v1alpha1/donothingpolicy.proto b/pkg/plugins/policies/donothingpolicy/api/v1alpha1/donothingpolicy.proto index 22e0fa2d2929..eb1dd1e0328b 100644 --- a/pkg/plugins/policies/donothingpolicy/api/v1alpha1/donothingpolicy.proto +++ b/pkg/plugins/policies/donothingpolicy/api/v1alpha1/donothingpolicy.proto @@ -35,11 +35,11 @@ message DoNothingPolicy { message To { // TargetRef is a reference to the resource that represents a group of // destinations. - kuma.common.v1alpha1.TargetRef targetRef = 1; + kuma.common.v1alpha1.TargetRef targetRef = 1 [ (doc.required) = true ]; // Default is a configuration specific to the group of destinations // referenced in 'targetRef' - Conf default = 2; + Conf default = 2 [ (doc.required) = true ]; } repeated To to = 2; @@ -47,11 +47,11 @@ message DoNothingPolicy { message From { // TargetRef is a reference to the resource that represents a group of // clients. - kuma.common.v1alpha1.TargetRef targetRef = 1; + kuma.common.v1alpha1.TargetRef targetRef = 1 [ (doc.required) = true ]; // Default is a configuration specific to the group of clients referenced in // 'targetRef' - Conf default = 2; + Conf default = 2 [ (doc.required) = true ]; } repeated From from = 3; diff --git a/pkg/plugins/policies/donothingpolicy/api/v1alpha1/validator.go b/pkg/plugins/policies/donothingpolicy/api/v1alpha1/validator.go index b755cafe9dcd..6c7bd4856549 100644 --- a/pkg/plugins/policies/donothingpolicy/api/v1alpha1/validator.go +++ b/pkg/plugins/policies/donothingpolicy/api/v1alpha1/validator.go @@ -9,57 +9,63 @@ import ( func (r *DoNothingPolicyResource) validate() error { var verr validators.ValidationError path := validators.RootedAt("spec") - - targetRefErr := matcher_validators.ValidateTargetRef(path.Field("targetRef"), r.Spec.GetTargetRef(), &matcher_validators.ValidateTargetRefOpts{ + verr.AddErrorAt(path.Field("targetRef"), validateTop(r.Spec.GetTargetRef())) + if len(r.Spec.GetTo()) == 0 && len(r.Spec.GetFrom()) == 0 { + verr.AddViolationAt(path, "at least one of 'from', 'to' has to be defined") + } + verr.AddErrorAt(path, validateTo(r.Spec.GetTo())) + verr.AddErrorAt(path, validateFrom(r.Spec.GetFrom())) + return verr.OrNil() +} +func validateTop(targetRef *common_proto.TargetRef) validators.ValidationError { + targetRefErr := matcher_validators.ValidateTargetRef(targetRef, &matcher_validators.ValidateTargetRefOpts{ SupportedKinds: []common_proto.TargetRef_Kind{ // TODO add supported TargetRef kinds for this policy }, }) - verr.AddError("", targetRefErr) - - from := path.Field("from") - if len(r.Spec.GetFrom()) == 0 { - verr.AddViolationAt(from, "cannot be empty") - } else { - for idx, fromItem := range r.Spec.GetFrom() { - targetRefErr := matcher_validators.ValidateTargetRef(from.Index(idx).Field("targetRef"), fromItem.GetTargetRef(), &matcher_validators.ValidateTargetRefOpts{ - SupportedKinds: []common_proto.TargetRef_Kind{ - // TODO add supported TargetRef for 'from' item - }, - }) - verr.AddError("", targetRefErr) + return targetRefErr +} +func validateFrom(from []*DoNothingPolicy_From) validators.ValidationError { + var verr validators.ValidationError + for idx, fromItem := range from { + path := validators.RootedAt("from").Index(idx) + verr.AddErrorAt(path.Field("targetRef"), matcher_validators.ValidateTargetRef(fromItem.GetTargetRef(), &matcher_validators.ValidateTargetRefOpts{ + SupportedKinds: []common_proto.TargetRef_Kind{ + // TODO add supported TargetRef for 'from' item + }, + })) - defaultField := from.Index(idx).Field("default") - if fromItem.GetDefault() == nil { - verr.AddViolationAt(defaultField, "cannot be nil") - } else { - // TODO add default conf validation - verr.AddViolationAt(defaultField, "") - } + defaultField := path.Field("default") + if fromItem.GetDefault() == nil { + verr.AddViolationAt(defaultField, "must be defined") + } else { + verr.AddErrorAt(defaultField, validateDefault(fromItem.Default)) } } + return verr +} +func validateTo(to []*DoNothingPolicy_To) validators.ValidationError { + var verr validators.ValidationError + for idx, toItem := range to { + path := validators.RootedAt("to").Index(idx) + verr.AddErrorAt(path.Field("targetRef"), matcher_validators.ValidateTargetRef(toItem.GetTargetRef(), &matcher_validators.ValidateTargetRefOpts{ + SupportedKinds: []common_proto.TargetRef_Kind{ + // TODO add supported TargetRef for 'to' item + }, + })) - to := path.Field("to") - if len(r.Spec.GetTo()) == 0 { - verr.AddViolationAt(to, "cannot be empty") - } else { - for idx, toItem := range r.Spec.GetTo() { - targetRefErr := matcher_validators.ValidateTargetRef(from.Index(idx).Field("targetRef"), toItem.GetTargetRef(), &matcher_validators.ValidateTargetRefOpts{ - SupportedKinds: []common_proto.TargetRef_Kind{ - // TODO add supported TargetRef for 'to' item - }, - }) - verr.AddError("", targetRefErr) - - defaultField := to.Index(idx).Field("default") - if toItem.GetDefault() == nil { - verr.AddViolationAt(defaultField, "cannot be nil") - } else { - // TODO add default conf validation - verr.AddViolationAt(defaultField, "") - } + defaultField := path.Field("default") + if toItem.GetDefault() == nil { + verr.AddViolationAt(defaultField, "must be defined") + } else { + verr.AddErrorAt(defaultField, validateDefault(toItem.Default)) } } + return verr +} - return verr.OrNil() +func validateDefault(conf *DoNothingPolicy_Conf) validators.ValidationError { + var verr validators.ValidationError + // TODO add default conf validation + return verr } diff --git a/pkg/plugins/policies/donothingpolicy/plugin/v1alpha1/plugin.go b/pkg/plugins/policies/donothingpolicy/plugin/v1alpha1/plugin.go index f3b308cda4d1..49adf707a86e 100644 --- a/pkg/plugins/policies/donothingpolicy/plugin/v1alpha1/plugin.go +++ b/pkg/plugins/policies/donothingpolicy/plugin/v1alpha1/plugin.go @@ -1,6 +1,7 @@ package v1alpha1 import ( + "github.com/kumahq/kuma/pkg/core" core_plugins "github.com/kumahq/kuma/pkg/core/plugins" core_mesh "github.com/kumahq/kuma/pkg/core/resources/apis/mesh" core_xds "github.com/kumahq/kuma/pkg/core/xds" @@ -10,6 +11,7 @@ import ( ) var _ core_plugins.PolicyPlugin = &plugin{} +var log = core.Log.WithName("DoNothingPolicy") type plugin struct { } @@ -23,5 +25,6 @@ func (p plugin) MatchedPolicies(dataplane *core_mesh.DataplaneResource, resource } func (p plugin) Apply(rs *core_xds.ResourceSet, ctx xds_context.Context, proxy *core_xds.Proxy) error { - panic("implement me") + log.Info("apply is not implemented") + return nil } diff --git a/pkg/plugins/policies/matchers/validators/validator.go b/pkg/plugins/policies/matchers/validators/validator.go index 811dbc93519a..bcf1a237d1c8 100644 --- a/pkg/plugins/policies/matchers/validators/validator.go +++ b/pkg/plugins/policies/matchers/validators/validator.go @@ -12,7 +12,6 @@ type ValidateTargetRefOpts struct { } func ValidateTargetRef( - path validators.PathBuilder, ref *common_proto.TargetRef, opts *ValidateTargetRefOpts, ) validators.ValidationError { @@ -22,50 +21,50 @@ func ValidateTargetRef( return verr } if !contains(opts.SupportedKinds, ref.GetKindEnum()) { - verr.AddViolationAt(path.Field("kind"), "value is not supported") + verr.AddViolation("kind", "value is not supported") } else { switch ref.GetKindEnum() { case common_proto.TargetRef_Mesh: if len(ref.Tags) != 0 { - verr.AddViolationAt(path.Field("tags"), fmt.Sprintf("could not be set with kind %v", common_proto.TargetRef_Mesh)) + verr.AddViolation("tags", fmt.Sprintf("could not be set with kind %v", common_proto.TargetRef_Mesh)) } if len(ref.Mesh) != 0 { - verr.AddViolationAt(path.Field("mesh"), fmt.Sprintf("could not be set with kind %v", common_proto.TargetRef_Mesh)) + verr.AddViolation("mesh", fmt.Sprintf("could not be set with kind %v", common_proto.TargetRef_Mesh)) } case common_proto.TargetRef_MeshSubset: if len(ref.Mesh) != 0 { - verr.AddViolationAt(path.Field("mesh"), fmt.Sprintf("could not be set with kind %v", common_proto.TargetRef_MeshSubset)) + verr.AddViolation("mesh", fmt.Sprintf("could not be set with kind %v", common_proto.TargetRef_MeshSubset)) } if ref.Tags != nil && len(ref.Tags) == 0 { - verr.AddViolationAt(path.Field("tags"), "cannot be empty") + verr.AddViolation("tags", "cannot be empty") } case common_proto.TargetRef_MeshService: if len(ref.Tags) != 0 { - verr.AddViolationAt(path.Field("tags"), fmt.Sprintf("could not be set with kind %v", common_proto.TargetRef_MeshService)) + verr.AddViolation("tags", fmt.Sprintf("could not be set with kind %v", common_proto.TargetRef_MeshService)) } if len(ref.Name) == 0 { - verr.AddViolationAt(path.Field("name"), "cannot be empty") + verr.AddViolation("name", "cannot be empty") } case common_proto.TargetRef_MeshServiceSubset: if len(ref.Name) == 0 { - verr.AddViolationAt(path.Field("name"), "cannot be empty") + verr.AddViolation("name", "cannot be empty") } if ref.Tags != nil && len(ref.Tags) == 0 { - verr.AddViolationAt(path.Field("tags"), "cannot be empty") + verr.AddViolation("tags", "cannot be empty") } case common_proto.TargetRef_MeshGatewayRoute: if len(ref.Name) == 0 { - verr.AddViolationAt(path.Field("name"), "cannot be empty") + verr.AddViolation("name", "cannot be empty") } if len(ref.Mesh) != 0 { - verr.AddViolationAt(path.Field("mesh"), fmt.Sprintf("could not be set with kind %v", common_proto.TargetRef_MeshGatewayRoute)) + verr.AddViolation("mesh", fmt.Sprintf("could not be set with kind %v", common_proto.TargetRef_MeshGatewayRoute)) } case common_proto.TargetRef_MeshHTTPRoute: if len(ref.Name) == 0 { - verr.AddViolationAt(path.Field("name"), "cannot be empty") + verr.AddViolation("name", "cannot be empty") } if len(ref.Mesh) != 0 { - verr.AddViolationAt(path.Field("mesh"), fmt.Sprintf("could not be set with kind %v", common_proto.TargetRef_MeshHTTPRoute)) + verr.AddViolation("mesh", fmt.Sprintf("could not be set with kind %v", common_proto.TargetRef_MeshHTTPRoute)) } } } diff --git a/pkg/plugins/policies/matchers/validators/validator_test.go b/pkg/plugins/policies/matchers/validators/validator_test.go index 516b9d018a47..8e0f61ea8f19 100644 --- a/pkg/plugins/policies/matchers/validators/validator_test.go +++ b/pkg/plugins/policies/matchers/validators/validator_test.go @@ -28,7 +28,8 @@ var _ = Describe("TargetRef Validator", func() { Expect(err).ToNot(HaveOccurred()) // when - validationErr := matcher_validators.ValidateTargetRef(validators.RootedAt("targetRef"), targetRef, given.opts) + validationErr := validators.ValidationError{} + validationErr.AddError("targetRef", matcher_validators.ValidateTargetRef(targetRef, given.opts)) // then Expect(validationErr.OrNil()).To(BeNil()) @@ -181,7 +182,8 @@ name: backend-http-route Expect(err).ToNot(HaveOccurred()) // when - validationErr := matcher_validators.ValidateTargetRef(validators.RootedAt("targetRef"), targetRef, given.opts) + validationErr := validators.ValidationError{} + validationErr.AddError("targetRef", matcher_validators.ValidateTargetRef(targetRef, given.opts)) // and actual, err := yaml.Marshal(validationErr) diff --git a/pkg/plugins/policies/meshaccesslog/api/v1alpha1/validator.go b/pkg/plugins/policies/meshaccesslog/api/v1alpha1/validator.go index e0ad3708a2e2..3b42ae8f4e55 100644 --- a/pkg/plugins/policies/meshaccesslog/api/v1alpha1/validator.go +++ b/pkg/plugins/policies/meshaccesslog/api/v1alpha1/validator.go @@ -12,149 +12,143 @@ import ( func (r *MeshAccessLogResource) validate() error { var verr validators.ValidationError - spec := validators.RootedAt("spec") + path := validators.RootedAt("spec") + verr.AddErrorAt(path.Field("targetRef"), validateTop(r.Spec.GetTargetRef())) + if len(r.Spec.GetTo()) == 0 && len(r.Spec.GetFrom()) == 0 { + verr.AddViolationAt(path, "at least one of 'from', 'to' has to be defined") + } + verr.AddErrorAt(path, validateTo(r.Spec.GetTo())) + verr.AddErrorAt(path, validateFrom(r.Spec.GetFrom())) + verr.AddErrorAt(path, validateIncompatibleCombinations(r.Spec)) + return verr.OrNil() +} +func validateTop(targetRef *common_proto.TargetRef) validators.ValidationError { + targetRefErr := matcher_validators.ValidateTargetRef(targetRef, &matcher_validators.ValidateTargetRefOpts{ + SupportedKinds: []common_proto.TargetRef_Kind{ + common_proto.TargetRef_Mesh, + common_proto.TargetRef_MeshSubset, + common_proto.TargetRef_MeshService, + common_proto.TargetRef_MeshServiceSubset, + common_proto.TargetRef_MeshGatewayRoute, + common_proto.TargetRef_MeshHTTPRoute, + }, + }) + return targetRefErr +} +func validateFrom(from []*MeshAccessLog_From) validators.ValidationError { + var verr validators.ValidationError + for idx, fromItem := range from { + path := validators.RootedAt("from").Index(idx) + verr.AddErrorAt(path.Field("targetRef"), matcher_validators.ValidateTargetRef(fromItem.GetTargetRef(), &matcher_validators.ValidateTargetRefOpts{ + SupportedKinds: []common_proto.TargetRef_Kind{ + common_proto.TargetRef_Mesh, + }, + })) - r.validateTop(spec, &verr) - r.validateFrom(spec, &verr) - r.validateTo(spec, &verr) - r.validateIncompatibleCombinations(spec, &verr) - r.validateToOrFromDefined(spec, &verr) + defaultField := path.Field("default") + if fromItem.GetDefault() == nil { + verr.AddViolationAt(defaultField, "must be defined") + } else { + verr.AddErrorAt(defaultField, validateDefault(fromItem.Default)) + } + } + return verr +} +func validateTo(to []*MeshAccessLog_To) validators.ValidationError { + var verr validators.ValidationError + for idx, toItem := range to { + path := validators.RootedAt("to").Index(idx) + verr.AddErrorAt(path.Field("targetRef"), matcher_validators.ValidateTargetRef(toItem.GetTargetRef(), &matcher_validators.ValidateTargetRefOpts{ + SupportedKinds: []common_proto.TargetRef_Kind{ + common_proto.TargetRef_Mesh, + common_proto.TargetRef_MeshService, + }, + })) - return verr.OrNil() + defaultField := path.Field("default") + if toItem.GetDefault() == nil { + verr.AddViolationAt(defaultField, "must be defined") + } else { + verr.AddErrorAt(defaultField, validateDefault(toItem.Default)) + } + } + return verr +} + +func validateDefault(conf *MeshAccessLog_Conf) validators.ValidationError { + var verr validators.ValidationError + for backendIdx, backend := range conf.Backends { + verr.AddErrorAt(validators.RootedAt("backends").Index(backendIdx), validateBackend(backend)) + } + return verr } -func (r *MeshAccessLogResource) validateBackend(backend *MeshAccessLog_Backend, verr *validators.ValidationError, backendIndexed validators.PathBuilder) { +func validateBackend(backend *MeshAccessLog_Backend) validators.ValidationError { + var verr validators.ValidationError file := bool2int(backend.GetFile() != nil) tcp := bool2int(backend.GetTcp() != nil) if file+tcp != 1 { - verr.AddViolationAt(backendIndexed, `backend can have only one type defined: tcp, file`) + verr.AddViolation("", `backend can have only one type defined: tcp, file`) } - r.validateFormats(backend, verr, backendIndexed) + verr.AddErrorAt(validators.RootedAt("file").Field("format"), validateFormat(backend.GetFile().GetFormat())) + verr.AddErrorAt(validators.RootedAt("tcp").Field("format"), validateFormat(backend.GetTcp().GetFormat())) if backend.GetFile() != nil { isFilePath, _ := govalidator.IsFilePath(backend.GetFile().GetPath()) if !isFilePath { - verr.AddViolationAt(backendIndexed.Field("file").Field("path"), `file backend requires a valid path`) + verr.AddViolationAt(validators.RootedAt("file").Field("path"), `file backend requires a valid path`) } } if backend.GetTcp() != nil { if !govalidator.IsURL(backend.GetTcp().GetAddress()) { - verr.AddViolationAt(backendIndexed.Field("tcp").Field("address"), `tcp backend requires valid address`) + verr.AddViolationAt(validators.RootedAt("tcp").Field("address"), `tcp backend requires valid address`) } } + return verr } -func (r *MeshAccessLogResource) validateFormats(backend *MeshAccessLog_Backend, verr *validators.ValidationError, backendIndexed validators.PathBuilder) { - var formats []*MeshAccessLog_Format - if backend.GetFile() != nil { - formats = append(formats, backend.GetFile().Format) - } - if backend.GetTcp() != nil { - formats = append(formats, backend.GetTcp().Format) +func validateFormat(format *MeshAccessLog_Format) validators.ValidationError { + var verr validators.ValidationError + if format == nil { + return verr } - for _, format := range formats { - plain := bool2int(format.GetPlain() != "") - json := bool2int(format.GetJson() != nil) + plain := bool2int(format.GetPlain() != "") + json := bool2int(format.GetJson() != nil) - if plain+json > 1 { - verr.AddViolationAt(backendIndexed, `format can only have one type defined: plain, json`) - } + if plain+json > 1 { + verr.AddViolation("", `format can only have one type defined: plain, json`) + } - if format.GetJson() != nil { - for idx, field := range format.GetJson() { - indexedField := backendIndexed.Field("json").Index(idx) - if field.GetKey() == "" { - verr.AddViolationAt(indexedField.Field("key"), `key cannot be empty`) - } - if field.GetValue() == "" { - verr.AddViolationAt(indexedField.Field("value"), `value cannot be empty`) - } - if !govalidator.IsJSON(fmt.Sprintf(`{"%s": "%s"}`, field.GetKey(), field.GetValue())) { - verr.AddViolationAt(indexedField, `is not a valid JSON object`) - } + if format.GetJson() != nil { + for idx, field := range format.GetJson() { + indexedField := validators.RootedAt("json").Index(idx) + if field.GetKey() == "" { + verr.AddViolationAt(indexedField.Field("key"), `key cannot be empty`) + } + if field.GetValue() == "" { + verr.AddViolationAt(indexedField.Field("value"), `value cannot be empty`) + } + if !govalidator.IsJSON(fmt.Sprintf(`{"%s": "%s"}`, field.GetKey(), field.GetValue())) { + verr.AddViolationAt(indexedField, `is not a valid JSON object`) } } } + return verr } -func (r *MeshAccessLogResource) validateToOrFromDefined(spec validators.PathBuilder, verr *validators.ValidationError) { - if len(r.Spec.GetFrom()) == 0 && len(r.Spec.GetTo()) == 0 { - verr.AddViolationAt(spec, `at least one of "from", "to" has to be defined`) - } -} - -func (r *MeshAccessLogResource) validateIncompatibleCombinations(spec validators.PathBuilder, verr *validators.ValidationError) { - to := spec.Field("to") - targetRef := r.Spec.GetTargetRef().GetKindEnum() - if targetRef == common_proto.TargetRef_MeshGatewayRoute && len(r.Spec.GetTo()) > 0 { - verr.AddViolationAt(to, `cannot use "to" when "targetRef" is "MeshGatewayRoute" - there is no outbound`) - } - if targetRef == common_proto.TargetRef_MeshHTTPRoute && len(r.Spec.GetTo()) > 0 { - verr.AddViolationAt(to, `cannot use "to" when "targetRef" is "MeshHTTPRoute" - "to" always goes to the application`) - } -} - -func (r *MeshAccessLogResource) validateTo(spec validators.PathBuilder, verr *validators.ValidationError) { - to := spec.Field("to") - for idx, toItem := range r.Spec.GetTo() { - targetRefErr := matcher_validators.ValidateTargetRef(to.Index(idx).Field("targetRef"), toItem.GetTargetRef(), &matcher_validators.ValidateTargetRefOpts{ - SupportedKinds: []common_proto.TargetRef_Kind{ - common_proto.TargetRef_Mesh, - common_proto.TargetRef_MeshService, - }, - }) - verr.AddError("", targetRefErr) - - if toItem.GetDefault() == nil { - verr.AddViolationAt(to.Index(idx).Field("default"), "must be defined") - } - - toIndexed := to.Index(idx) - for backendIdx, backend := range toItem.GetDefault().GetBackends() { - backendIndexed := toIndexed.Field("default").Field("backend").Index(backendIdx) - r.validateBackend(backend, verr, backendIndexed) - } +func validateIncompatibleCombinations(spec *MeshAccessLog) validators.ValidationError { + var verr validators.ValidationError + targetRef := spec.GetTargetRef().GetKindEnum() + if targetRef == common_proto.TargetRef_MeshGatewayRoute && len(spec.GetTo()) > 0 { + verr.AddViolation("to", `cannot use "to" when "targetRef" is "MeshGatewayRoute" - there is no outbound`) } -} - -func (r *MeshAccessLogResource) validateFrom(spec validators.PathBuilder, verr *validators.ValidationError) { - from := spec.Field("from") - for idx, fromItem := range r.Spec.GetFrom() { - targetRefErr := matcher_validators.ValidateTargetRef(from.Index(idx).Field("targetRef"), fromItem.GetTargetRef(), &matcher_validators.ValidateTargetRefOpts{ - SupportedKinds: []common_proto.TargetRef_Kind{ - common_proto.TargetRef_Mesh, - }, - }) - verr.AddError("", targetRefErr) - - if fromItem.GetDefault() == nil { - verr.AddViolationAt(from.Index(idx).Field("default"), "must be defined") - } - - toIndexed := from.Index(idx) - for backendIdx, backend := range fromItem.GetDefault().GetBackends() { - backendIndexed := toIndexed.Field("default").Field("backend").Index(backendIdx) - r.validateBackend(backend, verr, backendIndexed) - } + if targetRef == common_proto.TargetRef_MeshHTTPRoute && len(spec.GetTo()) > 0 { + verr.AddViolation("to", `cannot use "to" when "targetRef" is "MeshHTTPRoute" - "to" always goes to the application`) } -} - -func (r *MeshAccessLogResource) validateTop(spec validators.PathBuilder, verr *validators.ValidationError) { - top := spec.Field("targetRef") - targetRefErr := matcher_validators.ValidateTargetRef(top, r.Spec.GetTargetRef(), &matcher_validators.ValidateTargetRefOpts{ - SupportedKinds: []common_proto.TargetRef_Kind{ - common_proto.TargetRef_Mesh, - common_proto.TargetRef_MeshSubset, - common_proto.TargetRef_MeshService, - common_proto.TargetRef_MeshServiceSubset, - common_proto.TargetRef_MeshGatewayRoute, - common_proto.TargetRef_MeshHTTPRoute, - }, - }) - verr.AddError("", targetRefErr) + return verr } func bool2int(b bool) int { diff --git a/pkg/plugins/policies/meshaccesslog/api/v1alpha1/validator_test.go b/pkg/plugins/policies/meshaccesslog/api/v1alpha1/validator_test.go index fc483f84db33..03bca8e9f3be 100644 --- a/pkg/plugins/policies/meshaccesslog/api/v1alpha1/validator_test.go +++ b/pkg/plugins/policies/meshaccesslog/api/v1alpha1/validator_test.go @@ -97,7 +97,7 @@ targetRef: expected: ` violations: - field: spec - message: at least one of "from", "to" has to be defined`, + message: at least one of 'from', 'to' has to be defined`, }), Entry("empty 'path'", testCase{ inputYaml: ` @@ -116,7 +116,7 @@ from: `, expected: ` violations: - - field: spec.from[0].default.backend[0].file.path + - field: spec.from[0].default.backends[0].file.path message: file backend requires a valid path`, }), Entry("invalid 'path'", testCase{ @@ -137,7 +137,7 @@ from: `, expected: ` violations: - - field: spec.from[0].default.backend[0].file.path + - field: spec.from[0].default.backends[0].file.path message: file backend requires a valid path`, }), Entry("empty 'key'", testCase{ @@ -159,7 +159,7 @@ from: `, expected: ` violations: - - field: spec.from[0].default.backend[0].json[0].key + - field: spec.from[0].default.backends[0].file.format.json[0].key message: key cannot be empty`, }), Entry("empty 'value'", testCase{ @@ -181,7 +181,7 @@ from: `, expected: ` violations: - - field: spec.from[0].default.backend[0].json[0].value + - field: spec.from[0].default.backends[0].file.format.json[0].value message: value cannot be empty`, }), Entry("invalid 'key'", testCase{ @@ -204,7 +204,7 @@ from: `, expected: ` violations: - - field: spec.from[0].default.backend[0].json[0] + - field: spec.from[0].default.backends[0].file.format.json[0] message: is not a valid JSON object`, }), Entry("both 'plain' and 'json' defined", testCase{ @@ -228,7 +228,7 @@ from: `, expected: ` violations: -- field: spec.from[0].default.backend[0] +- field: spec.from[0].default.backends[0].tcp.format message: 'format can only have one type defined: plain, json'`, }), Entry("both 'tcp' and 'file' defined", testCase{ @@ -255,7 +255,7 @@ from: `, expected: ` violations: -- field: spec.from[0].default.backend[0] +- field: spec.from[0].default.backends[0] message: 'backend can have only one type defined: tcp, file'`, }), @@ -351,7 +351,7 @@ from: `, expected: ` violations: -- field: spec.from[0].default.backend[0].tcp.address +- field: spec.from[0].default.backends[0].tcp.address message: 'tcp backend requires valid address'`, }), ) diff --git a/pkg/plugins/policies/meshaccesslog/plugin/v1alpha1/plugin.go b/pkg/plugins/policies/meshaccesslog/plugin/v1alpha1/plugin.go index bc96dd321769..826fe9d6d01c 100644 --- a/pkg/plugins/policies/meshaccesslog/plugin/v1alpha1/plugin.go +++ b/pkg/plugins/policies/meshaccesslog/plugin/v1alpha1/plugin.go @@ -11,6 +11,7 @@ import ( ) var _ core_plugins.PolicyPlugin = &plugin{} +var log = core.Log.WithName("MeshAccessLog") type plugin struct { } @@ -24,6 +25,6 @@ func (p plugin) MatchedPolicies(dataplane *core_mesh.DataplaneResource, resource } func (p plugin) Apply(rs *core_xds.ResourceSet, ctx xds_context.Context, proxy *core_xds.Proxy) error { - core.Log.V(1).Info("MeshAccessLog apply is not implemented") + log.Info("apply is not implemented") return nil } diff --git a/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/meshtrafficpermission.pb.go b/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/meshtrafficpermission.pb.go index a1bfb961fbb0..65e3ce04998c 100644 --- a/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/meshtrafficpermission.pb.go +++ b/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/meshtrafficpermission.pb.go @@ -266,7 +266,7 @@ var file_pkg_plugins_policies_meshtrafficpermission_api_v1alpha1_meshtrafficperm 0x1f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x72, 0x65, 0x66, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x6b, 0x75, 0x6d, 0x61, 0x2d, 0x64, 0x6f, 0x63, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xef, 0x03, 0x0a, 0x15, 0x4d, 0x65, 0x73, 0x68, + 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfb, 0x03, 0x0a, 0x15, 0x4d, 0x65, 0x73, 0x68, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3d, 0x0a, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6b, 0x75, 0x6d, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, @@ -285,28 +285,29 @@ var file_pkg_plugins_policies_meshtrafficpermission_api_v1alpha1_meshtrafficperm 0x45, 0x4e, 0x59, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x53, 0x48, 0x41, 0x44, 0x4f, 0x57, 0x5f, 0x44, 0x45, 0x4e, 0x59, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x44, 0x45, 0x4e, 0x59, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x5f, 0x53, - 0x48, 0x41, 0x44, 0x4f, 0x57, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x10, 0x03, 0x1a, 0xb1, 0x01, - 0x0a, 0x04, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x3d, 0x0a, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x48, 0x41, 0x44, 0x4f, 0x57, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x10, 0x03, 0x1a, 0xbd, 0x01, + 0x0a, 0x04, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x43, 0x0a, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6b, 0x75, 0x6d, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x52, 0x09, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x52, 0x65, 0x66, 0x12, 0x6a, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x50, 0x2e, 0x6b, 0x75, 0x6d, 0x61, 0x2e, 0x70, 0x6c, - 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4d, 0x65, - 0x73, 0x68, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, - 0x74, 0x3a, 0x06, 0xb2, 0x8c, 0x89, 0xa6, 0x01, 0x00, 0x42, 0x86, 0x01, 0x5a, 0x4e, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x75, 0x6d, 0x61, 0x68, 0x71, 0x2f, - 0x6b, 0x75, 0x6d, 0x61, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, - 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x74, 0x72, - 0x61, 0x66, 0x66, 0x69, 0x63, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x8a, 0xb5, 0x18, 0x32, - 0x50, 0x01, 0xa2, 0x01, 0x15, 0x4d, 0x65, 0x73, 0x68, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, - 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0xf2, 0x01, 0x15, 0x6d, 0x65, 0x73, - 0x68, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x42, 0x04, 0x88, 0xb5, 0x18, 0x01, + 0x52, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x12, 0x70, 0x0a, 0x07, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x50, 0x2e, 0x6b, + 0x75, 0x6d, 0x61, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x69, 0x65, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, + 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x50, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x42, 0x04, + 0x88, 0xb5, 0x18, 0x01, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x06, 0xb2, + 0x8c, 0x89, 0xa6, 0x01, 0x00, 0x42, 0x86, 0x01, 0x5a, 0x4e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x75, 0x6d, 0x61, 0x68, 0x71, 0x2f, 0x6b, 0x75, 0x6d, 0x61, + 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2f, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, + 0x63, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x8a, 0xb5, 0x18, 0x32, 0x50, 0x01, 0xa2, 0x01, + 0x15, 0x4d, 0x65, 0x73, 0x68, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0xf2, 0x01, 0x15, 0x6d, 0x65, 0x73, 0x68, 0x74, 0x72, 0x61, + 0x66, 0x66, 0x69, 0x63, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/meshtrafficpermission.proto b/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/meshtrafficpermission.proto index 503f521739eb..07f8ee5b7195 100644 --- a/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/meshtrafficpermission.proto +++ b/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/meshtrafficpermission.proto @@ -48,11 +48,11 @@ message MeshTrafficPermission { message From { // TargetRef is a reference to the resource that represents a group of // clients. - kuma.common.v1alpha1.TargetRef targetRef = 1; + kuma.common.v1alpha1.TargetRef targetRef = 1 [ (doc.required) = true ]; // Default is a configuration specific to the group of clients referenced in // 'targetRef' - Conf default = 2; + Conf default = 2 [ (doc.required) = true ]; } // From is a list of pairs – a group of clients and action applied for it diff --git a/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/validator.go b/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/validator.go index 29856434354d..d499cace8ea8 100644 --- a/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/validator.go +++ b/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/validator.go @@ -9,8 +9,15 @@ import ( func (r *MeshTrafficPermissionResource) validate() error { var verr validators.ValidationError path := validators.RootedAt("spec") - - targetRefErr := matcher_validators.ValidateTargetRef(path.Field("targetRef"), r.Spec.GetTargetRef(), &matcher_validators.ValidateTargetRefOpts{ + verr.AddErrorAt(path.Field("targetRef"), validateTop(r.Spec.GetTargetRef())) + if len(r.Spec.GetFrom()) == 0 { + verr.AddViolationAt(path.Field("from"), "needs at least one item") + } + verr.AddErrorAt(path, validateFrom(r.Spec.GetFrom())) + return verr.OrNil() +} +func validateTop(targetRef *common_proto.TargetRef) validators.ValidationError { + targetRefErr := matcher_validators.ValidateTargetRef(targetRef, &matcher_validators.ValidateTargetRefOpts{ SupportedKinds: []common_proto.TargetRef_Kind{ common_proto.TargetRef_Mesh, common_proto.TargetRef_MeshSubset, @@ -20,28 +27,32 @@ func (r *MeshTrafficPermissionResource) validate() error { common_proto.TargetRef_MeshHTTPRoute, }, }) - verr.AddError("", targetRefErr) - - from := path.Field("from") - if len(r.Spec.GetFrom()) == 0 { - verr.AddViolationAt(from, "cannot be empty") - } else { - for idx, fromItem := range r.Spec.GetFrom() { - targetRefErr := matcher_validators.ValidateTargetRef(from.Index(idx).Field("targetRef"), fromItem.GetTargetRef(), &matcher_validators.ValidateTargetRefOpts{ - SupportedKinds: []common_proto.TargetRef_Kind{ - common_proto.TargetRef_Mesh, - common_proto.TargetRef_MeshSubset, - common_proto.TargetRef_MeshService, - common_proto.TargetRef_MeshServiceSubset, - }, - }) - verr.AddError("", targetRefErr) + return targetRefErr +} +func validateFrom(from []*MeshTrafficPermission_From) validators.ValidationError { + var verr validators.ValidationError + for idx, fromItem := range from { + path := validators.RootedAt("from").Index(idx) + verr.AddErrorAt(path.Field("targetRef"), matcher_validators.ValidateTargetRef(fromItem.GetTargetRef(), &matcher_validators.ValidateTargetRefOpts{ + SupportedKinds: []common_proto.TargetRef_Kind{ + common_proto.TargetRef_Mesh, + common_proto.TargetRef_MeshSubset, + common_proto.TargetRef_MeshService, + common_proto.TargetRef_MeshServiceSubset, + }, + })) - if fromItem.GetDefault() == nil { - verr.AddViolationAt(from.Index(idx).Field("default"), "cannot be nil") - } + defaultField := path.Field("default") + if fromItem.GetDefault() == nil { + verr.AddViolationAt(defaultField, "must be defined") + } else { + verr.AddErrorAt(defaultField, validateDefault(fromItem.Default)) } } + return verr +} - return verr.OrNil() +func validateDefault(conf *MeshTrafficPermission_Conf) validators.ValidationError { + var verr validators.ValidationError + return verr } diff --git a/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/validator_test.go b/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/validator_test.go index d0038266cd80..628080c95950 100644 --- a/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/validator_test.go +++ b/pkg/plugins/policies/meshtrafficpermission/api/v1alpha1/validator_test.go @@ -134,7 +134,7 @@ from: [] expected: ` violations: - field: spec.from - message: cannot be empty`, + message: needs at least one item`, }), Entry("empty 'from' array", testCase{ inputYaml: ` @@ -146,7 +146,7 @@ from: [] expected: ` violations: - field: spec.from - message: cannot be empty`, + message: needs at least one item`, }), Entry("not supported kinds in 'from' array", testCase{ inputYaml: ` @@ -182,7 +182,7 @@ from: expected: ` violations: - field: spec.from[0].default - message: cannot be nil + message: must be defined `, }), ) diff --git a/pkg/plugins/policies/meshtrafficpermission/plugin/v1alpha1/plugin.go b/pkg/plugins/policies/meshtrafficpermission/plugin/v1alpha1/plugin.go index dbd895263672..ff51bce07d0f 100644 --- a/pkg/plugins/policies/meshtrafficpermission/plugin/v1alpha1/plugin.go +++ b/pkg/plugins/policies/meshtrafficpermission/plugin/v1alpha1/plugin.go @@ -11,6 +11,7 @@ import ( ) var _ core_plugins.PolicyPlugin = &plugin{} +var log = core.Log.WithName("MeshTrafficPermission") type plugin struct { } @@ -24,6 +25,6 @@ func (p plugin) MatchedPolicies(dataplane *core_mesh.DataplaneResource, resource } func (p plugin) Apply(rs *core_xds.ResourceSet, ctx xds_context.Context, proxy *core_xds.Proxy) error { - core.Log.V(1).Info("MeshTrafficPermission apply is not implemented") + log.Info("apply is not implemented") return nil } diff --git a/tools/policy-gen/bootstrap/root.go b/tools/policy-gen/bootstrap/root.go index 2a8e5e924e08..f5c92dfc7b6c 100644 --- a/tools/policy-gen/bootstrap/root.go +++ b/tools/policy-gen/bootstrap/root.go @@ -201,11 +201,11 @@ message {{ .name }} { message To { // TargetRef is a reference to the resource that represents a group of // destinations. - kuma.common.v1alpha1.TargetRef targetRef = 1; + kuma.common.v1alpha1.TargetRef targetRef = 1 [ (doc.required) = true ]; // Default is a configuration specific to the group of destinations referenced in // 'targetRef' - Conf default = 2; + Conf default = 2 [ (doc.required) = true ]; } repeated To to = 2; @@ -216,11 +216,11 @@ message {{ .name }} { message From { // TargetRef is a reference to the resource that represents a group of // clients. - kuma.common.v1alpha1.TargetRef targetRef = 1; + kuma.common.v1alpha1.TargetRef targetRef = 1 [ (doc.required) = true ]; // Default is a configuration specific to the group of clients referenced in // 'targetRef' - Conf default = 2; + Conf default = 2 [ (doc.required) = true ]; } repeated From from = 3; @@ -233,6 +233,8 @@ var pluginTemplate = template.Must(template.New("").Option("missingkey=error").P `package {{ .version }} import ( + "github.com/kumahq/kuma/pkg/core" + core_plugins "github.com/kumahq/kuma/pkg/core/plugins" core_mesh "github.com/kumahq/kuma/pkg/core/resources/apis/mesh" core_xds "github.com/kumahq/kuma/pkg/core/xds" @@ -244,6 +246,7 @@ import ( ) var _ core_plugins.PolicyPlugin = &plugin{} +var log = core.Log.WithName("{{.name}}") type plugin struct { } @@ -261,7 +264,8 @@ func (p plugin) MatchedPolicies(dataplane *core_mesh.DataplaneResource, resource } func (p plugin) Apply(rs *core_xds.ResourceSet, ctx xds_context.Context, proxy *core_xds.Proxy) error { - panic("implement me") + log.Info("apply is not implemented") + return nil } `)) @@ -278,71 +282,90 @@ import ( func (r *{{.name}}Resource) validate() error { var verr validators.ValidationError - {{- if or .generateTargetRef (or .generateTo .generateFrom) }} path := validators.RootedAt("spec") - {{- else }} - // TODO add validation - {{- end}} {{- if .generateTargetRef }} + verr.AddErrorAt(path.Field("targetRef"), validateTop(r.Spec.GetTargetRef())) + {{- end }} + {{- if and .generateTo .generateFrom }} + if len(r.Spec.GetTo()) == 0 && len(r.Spec.GetFrom()) == 0 { + verr.AddViolationAt(path, "at least one of 'from', 'to' has to be defined") + } + {{- else if .generateTo }} + if len(r.Spec.GetTo()) == 0 { + verr.AddErrorAt(path.Field("to"), "needs at least one item") + } + {{- else if .generateFrom }} + if len(r.Spec.GetFrom()) == 0 { + verr.AddErrorAt(path.Field("from"), "needs at least one item") + } + {{- end }} + {{- if .generateTo }} + verr.AddErrorAt(path, validateTo(r.Spec.GetTo())) + {{- end }} + {{- if .generateFrom }} + verr.AddErrorAt(path, validateFrom(r.Spec.GetFrom())) + {{- end }} + return verr.OrNil() +} - targetRefErr := matcher_validators.ValidateTargetRef(path.Field("targetRef"), r.Spec.GetTargetRef(), &matcher_validators.ValidateTargetRefOpts{ +{{- if .generateTargetRef }} +func validateTop(targetRef *common_proto.TargetRef) validators.ValidationError { + targetRefErr := matcher_validators.ValidateTargetRef(targetRef, &matcher_validators.ValidateTargetRefOpts{ SupportedKinds: []common_proto.TargetRef_Kind{ // TODO add supported TargetRef kinds for this policy }, }) - verr.AddError("", targetRefErr) - {{- end}} - - {{- if .generateFrom }} + return targetRefErr +} +{{- end }} - from := path.Field("from") - if len(r.Spec.GetFrom()) == 0 { - verr.AddViolationAt(from, "cannot be empty") - } else { - for idx, fromItem := range r.Spec.GetFrom() { - targetRefErr := matcher_validators.ValidateTargetRef(from.Index(idx).Field("targetRef"), fromItem.GetTargetRef(), &matcher_validators.ValidateTargetRefOpts{ - SupportedKinds: []common_proto.TargetRef_Kind{ - // TODO add supported TargetRef for 'from' item - }, - }) - verr.AddError("", targetRefErr) - - defaultField := from.Index(idx).Field("default") - if fromItem.GetDefault() == nil { - verr.AddViolationAt(defaultField, "cannot be nil") - } else { - // TODO add default conf validation - verr.AddViolationAt(defaultField, "") - } - } +{{- if .generateFrom }} +func validateFrom(from []*{{.name}}_From) validators.ValidationError { + var verr validators.ValidationError + for idx, fromItem := range from { + path := validators.RootedAt("from").Index(idx) + verr.AddErrorAt(path.Field("targetRef"), matcher_validators.ValidateTargetRef(fromItem.GetTargetRef(), &matcher_validators.ValidateTargetRefOpts{ + SupportedKinds: []common_proto.TargetRef_Kind{ + // TODO add supported TargetRef for 'from' item + }, + })) + + defaultField := path.Field("default") + if fromItem.GetDefault() == nil { + verr.AddViolationAt(defaultField, "must be defined") + } else { + verr.AddErrorAt(defaultField, validateDefault(fromItem.Default)) + } } - {{- end}} - - {{- if .generateTo }} + return verr +} +{{- end }} - to := path.Field("to") - if len(r.Spec.GetTo()) == 0 { - verr.AddViolationAt(to, "cannot be empty") - } else { - for idx, toItem := range r.Spec.GetTo() { - targetRefErr := matcher_validators.ValidateTargetRef(from.Index(idx).Field("targetRef"), toItem.GetTargetRef(), &matcher_validators.ValidateTargetRefOpts{ - SupportedKinds: []common_proto.TargetRef_Kind{ - // TODO add supported TargetRef for 'to' item - }, - }) - verr.AddError("", targetRefErr) - - defaultField := to.Index(idx).Field("default") - if toItem.GetDefault() == nil { - verr.AddViolationAt(defaultField, "cannot be nil") - } else { - // TODO add default conf validation - verr.AddViolationAt(defaultField, "") - } - } +{{- if .generateTo }} +func validateTo(to []*{{.name}}_To) validators.ValidationError { + var verr validators.ValidationError + for idx, toItem := range to { + path := validators.RootedAt("to").Index(idx) + verr.AddErrorAt(path.Field("targetRef"), matcher_validators.ValidateTargetRef(toItem.GetTargetRef(), &matcher_validators.ValidateTargetRefOpts{ + SupportedKinds: []common_proto.TargetRef_Kind{ + // TODO add supported TargetRef for 'to' item + }, + })) + + defaultField := path.Field("default") + if toItem.GetDefault() == nil { + verr.AddViolationAt(defaultField, "must be defined") + } else { + verr.AddErrorAt(defaultField, validateDefault(toItem.Default)) + } } - {{- end}} + return verr +} +{{- end }} - return verr.OrNil() +func validateDefault(conf *{{.name}}_Conf) validators.ValidationError { + var verr validators.ValidationError + // TODO add default conf validation + return verr } `))