Merge pull request #40959 from mbohlool/tags
Automatic merge from submit-queue (batch tested with PRs 41037, 40118, 40959, 41084, 41092) Add OpenAPI extensions to openapi_gen (Definition Generator) fixes #40818
This commit is contained in:
		@@ -2,3 +2,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
- To generate definition for a specific type or package add "+k8s:openapi-gen=true" tag to the type/package comment lines.
 | 
					- To generate definition for a specific type or package add "+k8s:openapi-gen=true" tag to the type/package comment lines.
 | 
				
			||||||
- To exclude a type or a member from a tagged package/type, add "+k8s:openapi-gen=false" tag to the comment lines.
 | 
					- To exclude a type or a member from a tagged package/type, add "+k8s:openapi-gen=false" tag to the comment lines.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# OpenAPI Extensions
 | 
				
			||||||
 | 
					OpenAPI spec can have extensions on types. To define one or more extensions on a type or its member
 | 
				
			||||||
 | 
					add "+k8s:openapi-gen=x-kubernetes-$NAME:$VALUE" to the comment lines before type/member. A type/member can
 | 
				
			||||||
 | 
					have multiple extensions. The rest of the line in the comment will be used as $VALUE so there is no need to
 | 
				
			||||||
 | 
					escape or quote the value string. Extensions can be use to pass more information to client generators or
 | 
				
			||||||
 | 
					documentation generators. For example a type my have a friendly name to be displayed in documentation or
 | 
				
			||||||
 | 
					being used in a client's fluent interface.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,13 +42,15 @@ const tagOptional = "optional"
 | 
				
			|||||||
const (
 | 
					const (
 | 
				
			||||||
	tagValueTrue       = "true"
 | 
						tagValueTrue       = "true"
 | 
				
			||||||
	tagValueFalse      = "false"
 | 
						tagValueFalse      = "false"
 | 
				
			||||||
 | 
						tagExtensionPrefix = "x-kubernetes-"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getOpenAPITagValue(comments []string) []string {
 | 
				
			||||||
 | 
						return types.ExtractCommentTags("+", comments)[tagName]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func hasOpenAPITagValue(comments []string, value string) bool {
 | 
					func hasOpenAPITagValue(comments []string, value string) bool {
 | 
				
			||||||
	tagValues := types.ExtractCommentTags("+", comments)[tagName]
 | 
						tagValues := getOpenAPITagValue(comments)
 | 
				
			||||||
	if tagValues == nil {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for _, val := range tagValues {
 | 
						for _, val := range tagValues {
 | 
				
			||||||
		if val == value {
 | 
							if val == value {
 | 
				
			||||||
			return true
 | 
								return true
 | 
				
			||||||
@@ -342,6 +344,33 @@ func (g openAPITypeWriter) generate(t *types.Type) error {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			g.Do("\"$.$\",", k)
 | 
								g.Do("\"$.$\",", k)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							g.Do("},\n", nil)
 | 
				
			||||||
 | 
							if err := g.generateExtensions(t.CommentLines); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							g.Do("},\n", nil)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (g openAPITypeWriter) generateExtensions(CommentLines []string) error {
 | 
				
			||||||
 | 
						tagValues := getOpenAPITagValue(CommentLines)
 | 
				
			||||||
 | 
						anyExtension := false
 | 
				
			||||||
 | 
						for _, val := range tagValues {
 | 
				
			||||||
 | 
							if strings.HasPrefix(val, tagExtensionPrefix) {
 | 
				
			||||||
 | 
								if !anyExtension {
 | 
				
			||||||
 | 
									g.Do("spec.VendorExtensible: {\nExtensions: spec.Extensions{\n", nil)
 | 
				
			||||||
 | 
									anyExtension = true
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								parts := strings.SplitN(val, ":", 2)
 | 
				
			||||||
 | 
								if len(parts) != 2 {
 | 
				
			||||||
 | 
									return fmt.Errorf("Invalid extension value: %v", val)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								g.Do("\"$.$\": ", parts[0])
 | 
				
			||||||
 | 
								g.Do("\"$.$\",\n", parts[1])
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if anyExtension {
 | 
				
			||||||
		g.Do("},\n},\n", nil)
 | 
							g.Do("},\n},\n", nil)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
@@ -396,6 +425,9 @@ func (g openAPITypeWriter) generateProperty(m *types.Member) error {
 | 
				
			|||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	g.Do("\"$.$\": {\n", name)
 | 
						g.Do("\"$.$\": {\n", name)
 | 
				
			||||||
 | 
						if err := g.generateExtensions(m.CommentLines); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	g.Do("SchemaProps: spec.SchemaProps{\n", nil)
 | 
						g.Do("SchemaProps: spec.SchemaProps{\n", nil)
 | 
				
			||||||
	g.generateDescription(m.CommentLines)
 | 
						g.generateDescription(m.CommentLines)
 | 
				
			||||||
	jsonTags := getJsonTags(m)
 | 
						jsonTags := getJsonTags(m)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -71,7 +71,8 @@ func TestSimple(t *testing.T) {
 | 
				
			|||||||
package foo
 | 
					package foo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Blah is a test.
 | 
					// Blah is a test.
 | 
				
			||||||
// +k8s:openapi=true
 | 
					// +k8s:openapi-gen=true
 | 
				
			||||||
 | 
					// +k8s:openapi-gen=x-kubernetes-type-tag:type_test
 | 
				
			||||||
type Blah struct {
 | 
					type Blah struct {
 | 
				
			||||||
	// A simple string
 | 
						// A simple string
 | 
				
			||||||
	String string
 | 
						String string
 | 
				
			||||||
@@ -107,6 +108,9 @@ type Blah struct {
 | 
				
			|||||||
	Float32 float32
 | 
						Float32 float32
 | 
				
			||||||
	// a base64 encoded characters
 | 
						// a base64 encoded characters
 | 
				
			||||||
	ByteArray []byte
 | 
						ByteArray []byte
 | 
				
			||||||
 | 
						// a member with an extension
 | 
				
			||||||
 | 
						// +k8s:openapi-gen=x-kubernetes-member-tag:member_test
 | 
				
			||||||
 | 
						WithExtension string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		`)
 | 
							`)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -222,12 +226,29 @@ Type: []string{"string"},
 | 
				
			|||||||
Format: "byte",
 | 
					Format: "byte",
 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
 | 
					"WithExtension": {
 | 
				
			||||||
 | 
					spec.VendorExtensible: {
 | 
				
			||||||
 | 
					Extensions: spec.Extensions{
 | 
				
			||||||
 | 
					"x-kubernetes-member-tag": "member_test",
 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
Required: []string{"String","Int64","Int32","Int16","Int8","Uint","Uint64","Uint32","Uint16","Uint8","Byte","Bool","Float64","Float32","ByteArray"},
 | 
					},
 | 
				
			||||||
 | 
					SchemaProps: spec.SchemaProps{
 | 
				
			||||||
 | 
					Description: "a member with an extension",
 | 
				
			||||||
 | 
					Type: []string{"string"},
 | 
				
			||||||
 | 
					Format: "",
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					Required: []string{"String","Int64","Int32","Int16","Int8","Uint","Uint64","Uint32","Uint16","Uint8","Byte","Bool","Float64","Float32","ByteArray","WithExtension"},
 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
Dependencies: []string{
 | 
					Dependencies: []string{
 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
 | 
					spec.VendorExtensible: {
 | 
				
			||||||
 | 
					Extensions: spec.Extensions{
 | 
				
			||||||
 | 
					"x-kubernetes-type-tag": "type_test",
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
 | 
					},
 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
`, buffer.String())
 | 
					`, buffer.String())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user