Skip to content

Commit e56fc6b

Browse files
authored
Merge pull request #24 from solo-io/disable-validation-option
Add option to disable kubebuilder markers
2 parents f9b57d0 + 90bd6fe commit e56fc6b

File tree

7 files changed

+155
-1
lines changed

7 files changed

+155
-1
lines changed

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,6 @@ Other supported options are:
7373
* `proto_oneof`
7474
* when set to `true`, the openapi schema will include `oneOf` emulating the behavior of proto `oneof`.
7575
* `int_native`
76-
* when set to `true`, the native openapi schemas will be used for Integer types instead of Solo wrappers that add Kubernetes extension headers to the schema to treat int as strings
76+
* when set to `true`, the native openapi schemas will be used for Integer types instead of Solo wrappers that add Kubernetes extension headers to the schema to treat int as strings.
77+
* `disable_kube_markers`
78+
* when set to `true`, kubebuilder markers and validations such as PreserveUnknownFields, Required, default, and all CEL rules will be omitted from the OpenAPI schema. The Type marker will be maintained.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
changelog:
2+
- type: NEW_FEATURE
3+
issueLink: https://github.com/solo-io/gloo-mesh-enterprise/issues/17005
4+
resolvesIssue: false
5+
description: |
6+
Adds support for disabling kubebuilder markers and validations to omit them from the generated OpenAPI schema.

integration_test.go

+10
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,16 @@ func TestOpenAPIGeneration(t *testing.T) {
9999
},
100100
wantFiles: []string{"test6/openapiv3.yaml"},
101101
},
102+
{
103+
name: "Test disable_kube_markers option",
104+
id: "test7",
105+
perPackage: false,
106+
genOpts: "yaml=true,single_file=true,proto_oneof=true,int_native=true,multiline_description=true,disable_kube_markers=true",
107+
inputFiles: map[string][]string{
108+
"test7": {"./testdata/test7/markers.proto"},
109+
},
110+
wantFiles: []string{"test7/openapiv3.yaml"},
111+
},
102112
}
103113

104114
for _, tc := range testcases {

main.go

+11
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ func generate(request pluginpb.CodeGeneratorRequest) (*pluginpb.CodeGeneratorRes
5353
enumAsIntOrString := false
5454
protoOneof := false
5555
intNative := false
56+
disableKubeMarkers := false
5657

5758
var messagesWithEmptySchema []string
5859

@@ -137,6 +138,15 @@ func generate(request pluginpb.CodeGeneratorRequest) (*pluginpb.CodeGeneratorRes
137138
}
138139
} else if k == "additional_empty_schema" {
139140
messagesWithEmptySchema = strings.Split(v, "+")
141+
} else if k == "disable_kube_markers" {
142+
switch strings.ToLower(v) {
143+
case "true":
144+
disableKubeMarkers = true
145+
case "false":
146+
disableKubeMarkers = false
147+
default:
148+
return nil, fmt.Errorf("unknown value '%s' for disable_kube_markers", v)
149+
}
140150
} else {
141151
return nil, fmt.Errorf("unknown argument '%s' specified", k)
142152
}
@@ -173,6 +183,7 @@ func generate(request pluginpb.CodeGeneratorRequest) (*pluginpb.CodeGeneratorRes
173183
messagesWithEmptySchema,
174184
protoOneof,
175185
intNative,
186+
disableKubeMarkers,
176187
)
177188
return g.generateOutput(filesToGen)
178189
}

openapiGenerator.go

+9
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ type openapiGenerator struct {
116116
intNative bool
117117

118118
markerRegistry *markers.Registry
119+
120+
// If set to true, kubebuilder markers and validations such as PreserveUnknownFields, Required, default, and all CEL rules will be omitted from the OpenAPI schema.
121+
// The Type marker will be maintained.
122+
disableKubeMarkers bool
119123
}
120124

121125
type DescriptionConfiguration struct {
@@ -137,6 +141,7 @@ func newOpenAPIGenerator(
137141
messagesWithEmptySchema []string,
138142
protoOneof bool,
139143
intNative bool,
144+
disableKubeMarkers bool,
140145
) *openapiGenerator {
141146
mRegistry, err := markers.NewRegistry()
142147
if err != nil {
@@ -155,6 +160,7 @@ func newOpenAPIGenerator(
155160
protoOneof: protoOneof,
156161
intNative: intNative,
157162
markerRegistry: mRegistry,
163+
disableKubeMarkers: disableKubeMarkers,
158164
}
159165
}
160166

@@ -637,6 +643,9 @@ func (g *openapiGenerator) generateMultiLineDescription(desc protomodel.CoreDesc
637643
}
638644

639645
func (g *openapiGenerator) validationRules(desc protomodel.CoreDesc) []string {
646+
if g.disableKubeMarkers {
647+
return nil
648+
}
640649
_, validationRules := g.parseComments(desc)
641650
return validationRules
642651
}

testdata/golden/test7/openapiv3.yaml

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
components:
2+
schemas:
3+
test7.Msg:
4+
description: This is a top-level message.
5+
properties:
6+
a:
7+
format: int32
8+
type: integer
9+
blist:
10+
items:
11+
type: string
12+
type: array
13+
nested:
14+
properties:
15+
a:
16+
type: string
17+
b:
18+
type: string
19+
c:
20+
type: string
21+
d:
22+
type: string
23+
defaultValue:
24+
type: string
25+
embedded:
26+
type: string
27+
intOrString:
28+
type: string
29+
schemaless:
30+
description: Schemaless field
31+
type: string
32+
type: object
33+
object:
34+
description: Should maintain valid Type marker.
35+
type: object
36+
x-kubernetes-preserve-unknown-fields: true
37+
val:
38+
x-kubernetes-preserve-unknown-fields: true
39+
type: object
40+
info:
41+
title: OpenAPI Spec for Solo APIs.
42+
version: ""
43+
openapi: 3.0.1
44+
paths: null

testdata/test7/markers.proto

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
syntax = "proto3";
2+
3+
package test7;
4+
5+
import "struct.proto";
6+
7+
// This is a top-level message.
8+
//
9+
// +kubebuilder:pruning:PreserveUnknownFields
10+
message Msg {
11+
// +kubebuilder:pruning:PreserveUnknownFields
12+
Nested nested = 1;
13+
14+
// +kubebuilder:validation:Maximum=100
15+
// +kubebuilder:validation:Minimum=5
16+
// +kubebuilder:validation:ExclusiveMaximum=true
17+
// +kubebuilder:validation:ExclusiveMinimum=true
18+
// +kubebuilder:validation:MultipleOf=2
19+
// +kubebuilder:validation:XValidation:rule="self != 27",message="must not equal 27"
20+
int32 a = 2;
21+
22+
// +kubebuilder:validation:MinItems=1
23+
// +kubebuilder:validation:MaxItems=5
24+
// +kubebuilder:validation:UniqueItems=true
25+
repeated string blist = 3;
26+
27+
// +kubebuilder:validation:Type=value
28+
google.protobuf.Value val = 4;
29+
30+
// Should maintain valid Type marker.
31+
//
32+
// +kubebuilder:validation:Type=object
33+
google.protobuf.Struct object = 5;
34+
35+
// This is a nested message.
36+
//
37+
// +kubebuilder:validation:MinProperties=1
38+
// +kubebuilder:validation:MaxProperties=2
39+
message Nested {
40+
// +kubebuilder:validation:Pattern="^[a-zA-Z0-9_]*$"
41+
// +kubebuilder:validation:Required
42+
string a = 1;
43+
44+
// +kubebuilder:validation:Enum=Allow;Forbid;Replace
45+
// +kubebuilder:validation:Required
46+
string b = 2;
47+
48+
// +kubebuilder:validation:MaxLength=100
49+
// +kubebuilder:validation:MinLength=1
50+
string c = 3;
51+
52+
// +kubebuilder:validation:Format=date-time
53+
string d = 4;
54+
55+
// +kubebuilder:validation:XIntOrString
56+
string int_or_string = 5;
57+
58+
// +kubebuilder:default=forty-two
59+
// +kubebuilder:example=forty-two
60+
string default_value = 6;
61+
62+
// Schemaless field
63+
//
64+
// +kubebuilder:validation:Schemaless
65+
string schemaless = 7;
66+
67+
// +kubebuilder:validation:EmbeddedResource
68+
// +kubebuilder:validation:Nullable
69+
string embedded = 8;
70+
}
71+
}
72+

0 commit comments

Comments
 (0)