Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to disable kubebuilder markers #24

Merged
merged 6 commits into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,6 @@ Other supported options are:
* `proto_oneof`
* when set to `true`, the openapi schema will include `oneOf` emulating the behavior of proto `oneof`.
* `int_native`
* 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
* 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.
* `disable_kube_markers`
* 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.
6 changes: 6 additions & 0 deletions changelog/v0.2.3/disable-kube-markers-option.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
changelog:
- type: NEW_FEATURE
issueLink: https://github.com/solo-io/gloo-mesh-enterprise/issues/17005
resolvesIssue: false
description: |
Adds support for disabling kubebuilder markers and validations to omit them from the generated OpenAPI schema.
10 changes: 10 additions & 0 deletions integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,16 @@ func TestOpenAPIGeneration(t *testing.T) {
},
wantFiles: []string{"test6/openapiv3.yaml"},
},
{
name: "Test disable_kube_markers option",
id: "test7",
perPackage: false,
genOpts: "yaml=true,single_file=true,proto_oneof=true,int_native=true,multiline_description=true,disable_kube_markers=true",
inputFiles: map[string][]string{
"test7": {"./testdata/test7/markers.proto"},
},
wantFiles: []string{"test7/openapiv3.yaml"},
},
}

for _, tc := range testcases {
Expand Down
11 changes: 11 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func generate(request pluginpb.CodeGeneratorRequest) (*pluginpb.CodeGeneratorRes
enumAsIntOrString := false
protoOneof := false
intNative := false
disableKubeMarkers := false

var messagesWithEmptySchema []string

Expand Down Expand Up @@ -137,6 +138,15 @@ func generate(request pluginpb.CodeGeneratorRequest) (*pluginpb.CodeGeneratorRes
}
} else if k == "additional_empty_schema" {
messagesWithEmptySchema = strings.Split(v, "+")
} else if k == "disable_kube_markers" {
switch strings.ToLower(v) {
case "true":
disableKubeMarkers = true
case "false":
disableKubeMarkers = false
default:
return nil, fmt.Errorf("unknown value '%s' for disable_kube_markers", v)
}
} else {
return nil, fmt.Errorf("unknown argument '%s' specified", k)
}
Expand Down Expand Up @@ -173,6 +183,7 @@ func generate(request pluginpb.CodeGeneratorRequest) (*pluginpb.CodeGeneratorRes
messagesWithEmptySchema,
protoOneof,
intNative,
disableKubeMarkers,
)
return g.generateOutput(filesToGen)
}
Expand Down
9 changes: 9 additions & 0 deletions openapiGenerator.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ type openapiGenerator struct {
intNative bool

markerRegistry *markers.Registry

// If 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.
disableKubeMarkers bool
}

type DescriptionConfiguration struct {
Expand All @@ -137,6 +141,7 @@ func newOpenAPIGenerator(
messagesWithEmptySchema []string,
protoOneof bool,
intNative bool,
disableKubeMarkers bool,
) *openapiGenerator {
mRegistry, err := markers.NewRegistry()
if err != nil {
Expand All @@ -155,6 +160,7 @@ func newOpenAPIGenerator(
protoOneof: protoOneof,
intNative: intNative,
markerRegistry: mRegistry,
disableKubeMarkers: disableKubeMarkers,
}
}

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

func (g *openapiGenerator) validationRules(desc protomodel.CoreDesc) []string {
if g.disableKubeMarkers {
return nil
}
_, validationRules := g.parseComments(desc)
return validationRules
}
Expand Down
44 changes: 44 additions & 0 deletions testdata/golden/test7/openapiv3.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
components:
schemas:
test7.Msg:
description: This is a top-level message.
properties:
a:
format: int32
type: integer
blist:
items:
type: string
type: array
nested:
properties:
a:
type: string
b:
type: string
c:
type: string
d:
type: string
defaultValue:
type: string
embedded:
type: string
intOrString:
type: string
schemaless:
description: Schemaless field
type: string
type: object
object:
description: Should maintain valid Type marker.
type: object
x-kubernetes-preserve-unknown-fields: true
val:
x-kubernetes-preserve-unknown-fields: true
type: object
info:
title: OpenAPI Spec for Solo APIs.
version: ""
openapi: 3.0.1
paths: null
72 changes: 72 additions & 0 deletions testdata/test7/markers.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
syntax = "proto3";

package test7;

import "struct.proto";

// This is a top-level message.
//
// +kubebuilder:pruning:PreserveUnknownFields
message Msg {
// +kubebuilder:pruning:PreserveUnknownFields
Nested nested = 1;

// +kubebuilder:validation:Maximum=100
// +kubebuilder:validation:Minimum=5
// +kubebuilder:validation:ExclusiveMaximum=true
// +kubebuilder:validation:ExclusiveMinimum=true
// +kubebuilder:validation:MultipleOf=2
// +kubebuilder:validation:XValidation:rule="self != 27",message="must not equal 27"
int32 a = 2;

// +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:MaxItems=5
// +kubebuilder:validation:UniqueItems=true
repeated string blist = 3;

// +kubebuilder:validation:Type=value
google.protobuf.Value val = 4;

// Should maintain valid Type marker.
//
// +kubebuilder:validation:Type=object
google.protobuf.Struct object = 5;

// This is a nested message.
//
// +kubebuilder:validation:MinProperties=1
// +kubebuilder:validation:MaxProperties=2
message Nested {
// +kubebuilder:validation:Pattern="^[a-zA-Z0-9_]*$"
// +kubebuilder:validation:Required
string a = 1;

// +kubebuilder:validation:Enum=Allow;Forbid;Replace
// +kubebuilder:validation:Required
string b = 2;

// +kubebuilder:validation:MaxLength=100
// +kubebuilder:validation:MinLength=1
string c = 3;

// +kubebuilder:validation:Format=date-time
string d = 4;

// +kubebuilder:validation:XIntOrString
string int_or_string = 5;

// +kubebuilder:default=forty-two
// +kubebuilder:example=forty-two
string default_value = 6;

// Schemaless field
//
// +kubebuilder:validation:Schemaless
string schemaless = 7;

// +kubebuilder:validation:EmbeddedResource
// +kubebuilder:validation:Nullable
string embedded = 8;
}
}

Loading