diff --git a/pkg/kev/config/schema.go b/pkg/kev/config/schema.go index 6a1a8d9c8..6128c4043 100644 --- a/pkg/kev/config/schema.go +++ b/pkg/kev/config/schema.go @@ -67,6 +67,82 @@ var ServicesSchema = map[string]interface{}{ LabelWorkloadReplicas, LabelWorkloadLivenessProbeType, }, + "allOf": []map[string]interface{}{ + // Liveness probe + { + "oneOf": []map[string]interface{}{ + { + "properties": map[string]interface{}{ + LabelWorkloadLivenessProbeType: map[string]interface{}{ + "const": "http", + }, + }, + "required": []string{LabelWorkloadLivenessProbeHTTPPath, LabelWorkloadLivenessProbeHTTPPort}, + }, + { + "properties": map[string]interface{}{ + LabelWorkloadLivenessProbeType: map[string]interface{}{ + "const": "tcp", + }, + }, + "required": []string{LabelWorkloadLivenessProbeTCPPort}, + }, + { + "properties": map[string]interface{}{ + LabelWorkloadLivenessProbeType: map[string]interface{}{ + "const": "command", + }, + }, + "required": []string{LabelWorkloadLivenessProbeCommand}, + }, + // This acts as a catch all when the required properties are not provided, should come in the end + // otherwise instead of matching that "command" type needs a properties the error says the value is not "none". + { + "properties": map[string]interface{}{ + LabelWorkloadLivenessProbeType: map[string]interface{}{ + "const": "none", + }, + }, + }, + }, + }, + // Readiness probe + { + "anyOf": []map[string]interface{}{ + { + "properties": map[string]interface{}{ + LabelWorkloadReadinessProbeType: map[string]interface{}{ + "const": "http", + }, + }, + "required": []string{LabelWorkloadReadinessProbeHTTPPath, LabelWorkloadReadinessProbeHTTPPort}, + }, + { + "properties": map[string]interface{}{ + LabelWorkloadReadinessProbeType: map[string]interface{}{ + "const": "tcp", + }, + }, + "required": []string{LabelWorkloadReadinessProbeTCPPort}, + }, + { + "properties": map[string]interface{}{ + LabelWorkloadReadinessProbeType: map[string]interface{}{ + "const": "command", + }, + }, + "required": []string{LabelWorkloadReadinessProbeCommand}, + }, + { + "properties": map[string]interface{}{ + LabelWorkloadReadinessProbeType: map[string]interface{}{ + "const": "none", + }, + }, + }, + }, + }, + }, "additionalProperties": false, } diff --git a/pkg/kev/services.go b/pkg/kev/services.go index c59508dab..3dd344eb3 100644 --- a/pkg/kev/services.go +++ b/pkg/kev/services.go @@ -135,6 +135,23 @@ func (sc ServiceConfig) validate() error { } if !result.Valid() { + // Prioritise clear error messages. + for _, e := range result.Errors() { + if e.Type() == "required" { + return errors.New(e.Description()) + } + } + + for _, e := range result.Errors() { + // These errors are very cryptic and hurt usability. + if e.Type() == "number_one_of" || e.Type() == "number_any_of" || e.Type() == "number_all_of" { + continue + } + + return errors.New(e.Description()) + } + + // If we don't find anything useful just go with whatever is available. return errors.New(result.Errors()[0].Description()) } return nil diff --git a/pkg/kev/services_test.go b/pkg/kev/services_test.go index b086f83c2..090a4c453 100644 --- a/pkg/kev/services_test.go +++ b/pkg/kev/services_test.go @@ -38,7 +38,8 @@ var _ = Describe("ServiceConfig", func() { Expect(err).Should(MatchError(ContainSubstring(config.LabelWorkloadLivenessProbeType))) err = ServiceConfig{Labels: composego.Labels{ - config.LabelWorkloadLivenessProbeType: kubernetes.ProbeTypeCommand.String(), + config.LabelWorkloadLivenessProbeType: kubernetes.ProbeTypeCommand.String(), + config.LabelWorkloadLivenessProbeCommand: "echo i'm a useless probe", }}.validate() Expect(err).Should(MatchError(ContainSubstring(config.LabelWorkloadReplicas))) @@ -48,8 +49,9 @@ var _ = Describe("ServiceConfig", func() { It("success if the necessary labels are present", func() { err := ServiceConfig{Labels: composego.Labels{ - config.LabelWorkloadLivenessProbeType: kubernetes.ProbeTypeCommand.String(), - config.LabelWorkloadReplicas: "1", + config.LabelWorkloadLivenessProbeType: kubernetes.ProbeTypeCommand.String(), + config.LabelWorkloadLivenessProbeCommand: "echo i'm a useless probe", + config.LabelWorkloadReplicas: "1", }}.validate() Expect(err).NotTo(HaveOccurred()) })