Skip to content

Commit 08164d5

Browse files
Merge pull request #932 from meshery/feature/schema-validation
Add embedded Meshery schema validation
2 parents 877ccca + f703d93 commit 08164d5

File tree

14 files changed

+2093
-69
lines changed

14 files changed

+2093
-69
lines changed

errors/errors.go

Lines changed: 54 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
package errors
3838

3939
import (
40+
stderrors "errors"
4041
"fmt"
4142
"strings"
4243
)
@@ -172,83 +173,79 @@ func (e *Error) ErrorV2(additionalInfo interface{}) ErrorV2 {
172173
}
173174

174175
func GetCode(err error) string {
175-
var code string
176-
defer func() {
177-
if r := recover(); r != nil {
178-
code = strings.Join(NoneString[:], "")
179-
}
180-
}()
181-
if obj := err.(*Error); obj != nil && obj.Code != " " {
182-
code = obj.Code
183-
} else {
184-
code = strings.Join(NoneString[:], "")
176+
var errV2 *ErrorV2
177+
if stderrors.As(err, &errV2) && errV2 != nil && errV2.Code != " " {
178+
return errV2.Code
185179
}
186-
return code
180+
181+
var errV1 *Error
182+
if stderrors.As(err, &errV1) && errV1 != nil && errV1.Code != " " {
183+
return errV1.Code
184+
}
185+
return strings.Join(NoneString[:], "")
187186
}
188187

189188
func GetSeverity(err error) Severity {
190-
var severity Severity
191-
defer func() {
192-
if r := recover(); r != nil {
193-
severity = None
194-
}
195-
}()
196-
if obj := err.(*Error); obj != nil {
197-
severity = obj.Severity
198-
} else {
199-
severity = None
189+
var errV2 *ErrorV2
190+
if stderrors.As(err, &errV2) && errV2 != nil {
191+
return errV2.Severity
192+
}
193+
194+
var errV1 *Error
195+
if stderrors.As(err, &errV1) && errV1 != nil {
196+
return errV1.Severity
200197
}
201-
return severity
198+
return None
202199
}
203200

204201
func GetSDescription(err error) string {
205-
var description string
206-
defer func() {
207-
if r := recover(); r != nil {
208-
description = strings.Join(NoneString[:], "")
209-
}
210-
}()
211-
if obj := err.(*Error); obj != nil {
212-
description = strings.Join(obj.ShortDescription[:], ".")
213-
} else {
214-
description = strings.Join(NoneString[:], "")
202+
var errV2 *ErrorV2
203+
if stderrors.As(err, &errV2) && errV2 != nil {
204+
return strings.Join(errV2.ShortDescription[:], ".")
205+
}
206+
207+
var errV1 *Error
208+
if stderrors.As(err, &errV1) && errV1 != nil {
209+
return strings.Join(errV1.ShortDescription[:], ".")
215210
}
216-
return description
211+
return strings.Join(NoneString[:], "")
217212
}
218213

219214
func GetCause(err error) string {
220-
var cause string
221-
defer func() {
222-
if r := recover(); r != nil {
223-
cause = strings.Join(NoneString[:], "")
224-
}
225-
}()
226-
if obj := err.(*Error); obj != nil {
227-
cause = strings.Join(obj.ProbableCause[:], ".")
228-
} else {
229-
cause = strings.Join(NoneString[:], "")
215+
var errV2 *ErrorV2
216+
if stderrors.As(err, &errV2) && errV2 != nil {
217+
return strings.Join(errV2.ProbableCause[:], ".")
230218
}
231-
return cause
219+
220+
var errV1 *Error
221+
if stderrors.As(err, &errV1) && errV1 != nil {
222+
return strings.Join(errV1.ProbableCause[:], ".")
223+
}
224+
return strings.Join(NoneString[:], "")
232225
}
233226

234227
func GetRemedy(err error) string {
235-
var remedy string
236-
defer func() {
237-
if r := recover(); r != nil {
238-
remedy = strings.Join(NoneString[:], "")
239-
}
240-
}()
241-
if obj := err.(*Error); obj != nil {
242-
remedy = strings.Join(obj.SuggestedRemediation[:], ".")
243-
} else if err != nil {
244-
remedy = strings.Join(NoneString[:], "")
228+
var errV2 *ErrorV2
229+
if stderrors.As(err, &errV2) && errV2 != nil {
230+
return strings.Join(errV2.SuggestedRemediation[:], ".")
231+
}
232+
233+
var errV1 *Error
234+
if stderrors.As(err, &errV1) && errV1 != nil {
235+
return strings.Join(errV1.SuggestedRemediation[:], ".")
245236
}
246-
return remedy
237+
return strings.Join(NoneString[:], "")
247238
}
248239

249240
func GetLDescription(err error) string {
250-
if e, ok := err.(*Error); ok && e != nil {
251-
return strings.Join(e.LongDescription, ".")
241+
var errV2 *ErrorV2
242+
if stderrors.As(err, &errV2) && errV2 != nil {
243+
return strings.Join(errV2.LongDescription, ".")
244+
}
245+
246+
var errV1 *Error
247+
if stderrors.As(err, &errV1) && errV1 != nil {
248+
return strings.Join(errV1.LongDescription, ".")
252249
}
253250
return strings.Join(NoneString, "")
254251
}

errors/errors_test.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package errors
2+
3+
import (
4+
stderrors "errors"
5+
"fmt"
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestGettersSupportErrorV2(t *testing.T) {
12+
err := NewV2(
13+
"meshkit-99999",
14+
Alert,
15+
[]string{"short"},
16+
[]string{"long"},
17+
[]string{"cause"},
18+
[]string{"remedy"},
19+
map[string]string{"field": "value"},
20+
)
21+
22+
assert.Equal(t, "meshkit-99999", GetCode(err))
23+
assert.Equal(t, Severity(Alert), GetSeverity(err))
24+
assert.Equal(t, "short", GetSDescription(err))
25+
assert.Equal(t, "long", GetLDescription(err))
26+
assert.Equal(t, "cause", GetCause(err))
27+
assert.Equal(t, "remedy", GetRemedy(err))
28+
}
29+
30+
func TestGettersSupportWrappedErrorV2(t *testing.T) {
31+
err := fmt.Errorf("wrapped: %w", NewV2(
32+
"meshkit-99998",
33+
Critical,
34+
[]string{"wrapped short"},
35+
[]string{"wrapped long"},
36+
[]string{"wrapped cause"},
37+
[]string{"wrapped remedy"},
38+
nil,
39+
))
40+
41+
var errV2 *ErrorV2
42+
assert.True(t, stderrors.As(err, &errV2))
43+
assert.Equal(t, "meshkit-99998", GetCode(err))
44+
assert.Equal(t, Severity(Critical), GetSeverity(err))
45+
assert.Equal(t, "wrapped short", GetSDescription(err))
46+
assert.Equal(t, "wrapped long", GetLDescription(err))
47+
assert.Equal(t, "wrapped cause", GetCause(err))
48+
assert.Equal(t, "wrapped remedy", GetRemedy(err))
49+
}
50+
51+
type wrappedErrorV2 struct {
52+
v1 *Error
53+
v2 *ErrorV2
54+
}
55+
56+
func (e wrappedErrorV2) Error() string {
57+
return "wrapped error"
58+
}
59+
60+
func (e wrappedErrorV2) As(target any) bool {
61+
switch t := target.(type) {
62+
case **ErrorV2:
63+
*t = e.v2
64+
return true
65+
case **Error:
66+
*t = e.v1
67+
return true
68+
default:
69+
return false
70+
}
71+
}
72+
73+
func TestGettersPreferErrorV2WhenBothMatch(t *testing.T) {
74+
err := wrappedErrorV2{
75+
v1: New(
76+
"meshkit-00001",
77+
Alert,
78+
[]string{"v1 short"},
79+
[]string{"v1 long"},
80+
[]string{"v1 cause"},
81+
[]string{"v1 remedy"},
82+
),
83+
v2: NewV2(
84+
"meshkit-00002",
85+
Critical,
86+
[]string{"v2 short"},
87+
[]string{"v2 long"},
88+
[]string{"v2 cause"},
89+
[]string{"v2 remedy"},
90+
map[string]string{"field": "value"},
91+
),
92+
}
93+
94+
assert.Equal(t, "meshkit-00002", GetCode(err))
95+
assert.Equal(t, Severity(Critical), GetSeverity(err))
96+
assert.Equal(t, "v2 short", GetSDescription(err))
97+
assert.Equal(t, "v2 long", GetLDescription(err))
98+
assert.Equal(t, "v2 cause", GetCause(err))
99+
assert.Equal(t, "v2 remedy", GetRemedy(err))
100+
}

errors/types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ type (
99
ProbableCause []string
1010
SuggestedRemediation []string
1111
}
12-
// Limitations of Error struct defined above:
12+
// ErrorV2 addresses limitations of the Error struct defined above:
1313
// There are different types of Errors. Each type of error contains different information.
1414
// Short and Long Descriptions accept only strings and so they cannot contain structured information.
1515
// e.g. The Validation Error information (instancePath, badValue etc.) cannot be contained in Error struct (or not in a structured way that the clients can make use of it)

go.mod

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ replace (
1515
require (
1616
cuelang.org/go v0.15.1
1717
github.com/Masterminds/semver/v3 v3.4.0
18+
github.com/dlclark/regexp2 v1.11.0
1819
github.com/docker/cli v27.5.1+incompatible
1920
github.com/fluxcd/pkg/oci v0.43.1
2021
github.com/fluxcd/pkg/tar v0.10.0
@@ -27,7 +28,7 @@ require (
2728
github.com/google/uuid v1.6.0
2829
github.com/kubernetes/kompose v1.37.0
2930
github.com/meshery/meshery-operator v0.8.11
30-
github.com/meshery/schemas v0.8.113
31+
github.com/meshery/schemas v0.8.127
3132
github.com/nats-io/nats.go v1.47.0
3233
github.com/open-policy-agent/opa v1.11.0
3334
github.com/opencontainers/image-spec v1.1.1
@@ -206,7 +207,7 @@ require (
206207
github.com/lestrrat-go/httprc/v3 v3.0.2 // indirect
207208
github.com/lestrrat-go/jwx/v3 v3.0.12 // indirect
208209
github.com/lestrrat-go/option/v2 v2.0.0 // indirect
209-
github.com/lib/pq v1.10.9 // indirect
210+
github.com/lib/pq v1.11.2 // indirect
210211
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
211212
github.com/mailru/easyjson v0.9.0 // indirect
212213
github.com/mattn/go-colorable v0.1.14 // indirect
@@ -236,7 +237,7 @@ require (
236237
github.com/nats-io/nkeys v0.4.12 // indirect
237238
github.com/nats-io/nuid v1.0.1 // indirect
238239
github.com/novln/docker-parser v1.0.0 // indirect
239-
github.com/oapi-codegen/runtime v1.1.2 // indirect
240+
github.com/oapi-codegen/runtime v1.2.0 // indirect
240241
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect
241242
github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect
242243
github.com/opencontainers/go-digest v1.0.0 // indirect

go.sum

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,9 @@ github.com/lestrrat-go/jwx/v3 v3.0.12 h1:p25r68Y4KrbBdYjIsQweYxq794CtGCzcrc5dGzJ
415415
github.com/lestrrat-go/jwx/v3 v3.0.12/go.mod h1:HiUSaNmMLXgZ08OmGBaPVvoZQgJVOQphSrGr5zMamS8=
416416
github.com/lestrrat-go/option/v2 v2.0.0 h1:XxrcaJESE1fokHy3FpaQ/cXW8ZsIdWcdFzzLOcID3Ss=
417417
github.com/lestrrat-go/option/v2 v2.0.0/go.mod h1:oSySsmzMoR0iRzCDCaUfsCzxQHUEuhOViQObyy7S6Vg=
418-
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
419418
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
419+
github.com/lib/pq v1.11.2 h1:x6gxUeu39V0BHZiugWe8LXZYZ+Utk7hSJGThs8sdzfs=
420+
github.com/lib/pq v1.11.2/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA=
420421
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
421422
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
422423
github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY=
@@ -436,8 +437,8 @@ github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuE
436437
github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
437438
github.com/meshery/meshery-operator v0.8.11 h1:eDo2Sw0jjVrXsvvhF8LenADM58pK+7Z68ROPVIejTPc=
438439
github.com/meshery/meshery-operator v0.8.11/go.mod h1:hQEtFKKa5Fr/Mskk6bV5ip3bQ0+3F0u1voYS3XisBp4=
439-
github.com/meshery/schemas v0.8.113 h1:gQMKIJSKGTT6PuJje0XTxuHfCv9ERVLX9IrG1JyFAM8=
440-
github.com/meshery/schemas v0.8.113/go.mod h1:UwoDPg3j/2BMfytdgaalpemRKUxB9HhFsUZqJA01/G4=
440+
github.com/meshery/schemas v0.8.127 h1:MHR0sotqeZFjGsFYd+uQHP+fhOWcpAKyN9gaNWeuP6o=
441+
github.com/meshery/schemas v0.8.127/go.mod h1:5sD1I33x+J/oSIwYIdccH4VTVRQ71QCN7dUPvpqmESw=
441442
github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
442443
github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk=
443444
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
@@ -488,8 +489,8 @@ github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
488489
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
489490
github.com/novln/docker-parser v1.0.0 h1:PjEBd9QnKixcWczNGyEdfUrP6GR0YUilAqG7Wksg3uc=
490491
github.com/novln/docker-parser v1.0.0/go.mod h1:oCeM32fsoUwkwByB5wVjsrsVQySzPWkl3JdlTn1txpE=
491-
github.com/oapi-codegen/runtime v1.1.2 h1:P2+CubHq8fO4Q6fV1tqDBZHCwpVpvPg7oKiYzQgXIyI=
492-
github.com/oapi-codegen/runtime v1.1.2/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg=
492+
github.com/oapi-codegen/runtime v1.2.0 h1:RvKc1CVS1QeKSNzO97FBQbSMZyQ8s6rZd+LpmzwHMP4=
493+
github.com/oapi-codegen/runtime v1.2.0/go.mod h1:Y7ZhmmlE8ikZOmuHRRndiIm7nf3xcVv+YMweKgG1DT0=
493494
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY=
494495
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw=
495496
github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c=
@@ -603,8 +604,8 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
603604
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
604605
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
605606
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
606-
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
607-
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
607+
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
608+
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
608609
github.com/valyala/fastjson v1.6.5 h1:LLabX0wszE1JDH9+IxLK6b+tb4B7gNdTEFTRasd0Ejw=
609610
github.com/valyala/fastjson v1.6.5/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
610611
github.com/vbatts/tar-split v0.12.2 h1:w/Y6tjxpeiFMR47yzZPlPj/FcPLpXbTUi/9H7d3CPa4=

helpers/component_info.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"name": "meshkit",
33
"type": "library",
4-
"next_error_code": 11320
4+
"next_error_code": 11327
55
}

0 commit comments

Comments
 (0)