mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Update Godeps to use kube-openapi
This commit is contained in:
		
							
								
								
									
										24
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										24
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							@@ -3032,6 +3032,30 @@
 | 
				
			|||||||
			"Comment": "v1.2.0-beta.1",
 | 
								"Comment": "v1.2.0-beta.1",
 | 
				
			||||||
			"Rev": "c2ac40f1adf8c42a79badddb2a2acd673cae3bcb"
 | 
								"Rev": "c2ac40f1adf8c42a79badddb2a2acd673cae3bcb"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"ImportPath": "k8s.io/kube-openapi/pkg/aggregator",
 | 
				
			||||||
 | 
								"Rev": "80f07ef71bb4f781233c65aa8d0369e4ecafab87"
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"ImportPath": "k8s.io/kube-openapi/pkg/builder",
 | 
				
			||||||
 | 
								"Rev": "80f07ef71bb4f781233c65aa8d0369e4ecafab87"
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"ImportPath": "k8s.io/kube-openapi/pkg/common",
 | 
				
			||||||
 | 
								"Rev": "80f07ef71bb4f781233c65aa8d0369e4ecafab87"
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"ImportPath": "k8s.io/kube-openapi/pkg/generators",
 | 
				
			||||||
 | 
								"Rev": "80f07ef71bb4f781233c65aa8d0369e4ecafab87"
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"ImportPath": "k8s.io/kube-openapi/pkg/handler",
 | 
				
			||||||
 | 
								"Rev": "80f07ef71bb4f781233c65aa8d0369e4ecafab87"
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"ImportPath": "k8s.io/kube-openapi/pkg/util",
 | 
				
			||||||
 | 
								"Rev": "80f07ef71bb4f781233c65aa8d0369e4ecafab87"
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "k8s.io/utils/exec",
 | 
								"ImportPath": "k8s.io/utils/exec",
 | 
				
			||||||
			"Rev": "9fdc871a36f37980dd85f96d576b20d564cc0784"
 | 
								"Rev": "9fdc871a36f37980dd85f96d576b20d564cc0784"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1260
									
								
								Godeps/LICENSES
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1260
									
								
								Godeps/LICENSES
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										202
									
								
								vendor/k8s.io/kube-openapi/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								vendor/k8s.io/kube-openapi/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,202 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					                                 Apache License
 | 
				
			||||||
 | 
					                           Version 2.0, January 2004
 | 
				
			||||||
 | 
					                        http://www.apache.org/licenses/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   1. Definitions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "License" shall mean the terms and conditions for use, reproduction,
 | 
				
			||||||
 | 
					      and distribution as defined by Sections 1 through 9 of this document.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Licensor" shall mean the copyright owner or entity authorized by
 | 
				
			||||||
 | 
					      the copyright owner that is granting the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Legal Entity" shall mean the union of the acting entity and all
 | 
				
			||||||
 | 
					      other entities that control, are controlled by, or are under common
 | 
				
			||||||
 | 
					      control with that entity. For the purposes of this definition,
 | 
				
			||||||
 | 
					      "control" means (i) the power, direct or indirect, to cause the
 | 
				
			||||||
 | 
					      direction or management of such entity, whether by contract or
 | 
				
			||||||
 | 
					      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
				
			||||||
 | 
					      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "You" (or "Your") shall mean an individual or Legal Entity
 | 
				
			||||||
 | 
					      exercising permissions granted by this License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Source" form shall mean the preferred form for making modifications,
 | 
				
			||||||
 | 
					      including but not limited to software source code, documentation
 | 
				
			||||||
 | 
					      source, and configuration files.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Object" form shall mean any form resulting from mechanical
 | 
				
			||||||
 | 
					      transformation or translation of a Source form, including but
 | 
				
			||||||
 | 
					      not limited to compiled object code, generated documentation,
 | 
				
			||||||
 | 
					      and conversions to other media types.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Work" shall mean the work of authorship, whether in Source or
 | 
				
			||||||
 | 
					      Object form, made available under the License, as indicated by a
 | 
				
			||||||
 | 
					      copyright notice that is included in or attached to the work
 | 
				
			||||||
 | 
					      (an example is provided in the Appendix below).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Derivative Works" shall mean any work, whether in Source or Object
 | 
				
			||||||
 | 
					      form, that is based on (or derived from) the Work and for which the
 | 
				
			||||||
 | 
					      editorial revisions, annotations, elaborations, or other modifications
 | 
				
			||||||
 | 
					      represent, as a whole, an original work of authorship. For the purposes
 | 
				
			||||||
 | 
					      of this License, Derivative Works shall not include works that remain
 | 
				
			||||||
 | 
					      separable from, or merely link (or bind by name) to the interfaces of,
 | 
				
			||||||
 | 
					      the Work and Derivative Works thereof.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Contribution" shall mean any work of authorship, including
 | 
				
			||||||
 | 
					      the original version of the Work and any modifications or additions
 | 
				
			||||||
 | 
					      to that Work or Derivative Works thereof, that is intentionally
 | 
				
			||||||
 | 
					      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
				
			||||||
 | 
					      or by an individual or Legal Entity authorized to submit on behalf of
 | 
				
			||||||
 | 
					      the copyright owner. For the purposes of this definition, "submitted"
 | 
				
			||||||
 | 
					      means any form of electronic, verbal, or written communication sent
 | 
				
			||||||
 | 
					      to the Licensor or its representatives, including but not limited to
 | 
				
			||||||
 | 
					      communication on electronic mailing lists, source code control systems,
 | 
				
			||||||
 | 
					      and issue tracking systems that are managed by, or on behalf of, the
 | 
				
			||||||
 | 
					      Licensor for the purpose of discussing and improving the Work, but
 | 
				
			||||||
 | 
					      excluding communication that is conspicuously marked or otherwise
 | 
				
			||||||
 | 
					      designated in writing by the copyright owner as "Not a Contribution."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
				
			||||||
 | 
					      on behalf of whom a Contribution has been received by Licensor and
 | 
				
			||||||
 | 
					      subsequently incorporated within the Work.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
				
			||||||
 | 
					      this License, each Contributor hereby grants to You a perpetual,
 | 
				
			||||||
 | 
					      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
				
			||||||
 | 
					      copyright license to reproduce, prepare Derivative Works of,
 | 
				
			||||||
 | 
					      publicly display, publicly perform, sublicense, and distribute the
 | 
				
			||||||
 | 
					      Work and such Derivative Works in Source or Object form.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   3. Grant of Patent License. Subject to the terms and conditions of
 | 
				
			||||||
 | 
					      this License, each Contributor hereby grants to You a perpetual,
 | 
				
			||||||
 | 
					      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
				
			||||||
 | 
					      (except as stated in this section) patent license to make, have made,
 | 
				
			||||||
 | 
					      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
				
			||||||
 | 
					      where such license applies only to those patent claims licensable
 | 
				
			||||||
 | 
					      by such Contributor that are necessarily infringed by their
 | 
				
			||||||
 | 
					      Contribution(s) alone or by combination of their Contribution(s)
 | 
				
			||||||
 | 
					      with the Work to which such Contribution(s) was submitted. If You
 | 
				
			||||||
 | 
					      institute patent litigation against any entity (including a
 | 
				
			||||||
 | 
					      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
				
			||||||
 | 
					      or a Contribution incorporated within the Work constitutes direct
 | 
				
			||||||
 | 
					      or contributory patent infringement, then any patent licenses
 | 
				
			||||||
 | 
					      granted to You under this License for that Work shall terminate
 | 
				
			||||||
 | 
					      as of the date such litigation is filed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   4. Redistribution. You may reproduce and distribute copies of the
 | 
				
			||||||
 | 
					      Work or Derivative Works thereof in any medium, with or without
 | 
				
			||||||
 | 
					      modifications, and in Source or Object form, provided that You
 | 
				
			||||||
 | 
					      meet the following conditions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (a) You must give any other recipients of the Work or
 | 
				
			||||||
 | 
					          Derivative Works a copy of this License; and
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (b) You must cause any modified files to carry prominent notices
 | 
				
			||||||
 | 
					          stating that You changed the files; and
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (c) You must retain, in the Source form of any Derivative Works
 | 
				
			||||||
 | 
					          that You distribute, all copyright, patent, trademark, and
 | 
				
			||||||
 | 
					          attribution notices from the Source form of the Work,
 | 
				
			||||||
 | 
					          excluding those notices that do not pertain to any part of
 | 
				
			||||||
 | 
					          the Derivative Works; and
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (d) If the Work includes a "NOTICE" text file as part of its
 | 
				
			||||||
 | 
					          distribution, then any Derivative Works that You distribute must
 | 
				
			||||||
 | 
					          include a readable copy of the attribution notices contained
 | 
				
			||||||
 | 
					          within such NOTICE file, excluding those notices that do not
 | 
				
			||||||
 | 
					          pertain to any part of the Derivative Works, in at least one
 | 
				
			||||||
 | 
					          of the following places: within a NOTICE text file distributed
 | 
				
			||||||
 | 
					          as part of the Derivative Works; within the Source form or
 | 
				
			||||||
 | 
					          documentation, if provided along with the Derivative Works; or,
 | 
				
			||||||
 | 
					          within a display generated by the Derivative Works, if and
 | 
				
			||||||
 | 
					          wherever such third-party notices normally appear. The contents
 | 
				
			||||||
 | 
					          of the NOTICE file are for informational purposes only and
 | 
				
			||||||
 | 
					          do not modify the License. You may add Your own attribution
 | 
				
			||||||
 | 
					          notices within Derivative Works that You distribute, alongside
 | 
				
			||||||
 | 
					          or as an addendum to the NOTICE text from the Work, provided
 | 
				
			||||||
 | 
					          that such additional attribution notices cannot be construed
 | 
				
			||||||
 | 
					          as modifying the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      You may add Your own copyright statement to Your modifications and
 | 
				
			||||||
 | 
					      may provide additional or different license terms and conditions
 | 
				
			||||||
 | 
					      for use, reproduction, or distribution of Your modifications, or
 | 
				
			||||||
 | 
					      for any such Derivative Works as a whole, provided Your use,
 | 
				
			||||||
 | 
					      reproduction, and distribution of the Work otherwise complies with
 | 
				
			||||||
 | 
					      the conditions stated in this License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
				
			||||||
 | 
					      any Contribution intentionally submitted for inclusion in the Work
 | 
				
			||||||
 | 
					      by You to the Licensor shall be under the terms and conditions of
 | 
				
			||||||
 | 
					      this License, without any additional terms or conditions.
 | 
				
			||||||
 | 
					      Notwithstanding the above, nothing herein shall supersede or modify
 | 
				
			||||||
 | 
					      the terms of any separate license agreement you may have executed
 | 
				
			||||||
 | 
					      with Licensor regarding such Contributions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   6. Trademarks. This License does not grant permission to use the trade
 | 
				
			||||||
 | 
					      names, trademarks, service marks, or product names of the Licensor,
 | 
				
			||||||
 | 
					      except as required for reasonable and customary use in describing the
 | 
				
			||||||
 | 
					      origin of the Work and reproducing the content of the NOTICE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
				
			||||||
 | 
					      agreed to in writing, Licensor provides the Work (and each
 | 
				
			||||||
 | 
					      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
				
			||||||
 | 
					      implied, including, without limitation, any warranties or conditions
 | 
				
			||||||
 | 
					      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
				
			||||||
 | 
					      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
				
			||||||
 | 
					      appropriateness of using or redistributing the Work and assume any
 | 
				
			||||||
 | 
					      risks associated with Your exercise of permissions under this License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   8. Limitation of Liability. In no event and under no legal theory,
 | 
				
			||||||
 | 
					      whether in tort (including negligence), contract, or otherwise,
 | 
				
			||||||
 | 
					      unless required by applicable law (such as deliberate and grossly
 | 
				
			||||||
 | 
					      negligent acts) or agreed to in writing, shall any Contributor be
 | 
				
			||||||
 | 
					      liable to You for damages, including any direct, indirect, special,
 | 
				
			||||||
 | 
					      incidental, or consequential damages of any character arising as a
 | 
				
			||||||
 | 
					      result of this License or out of the use or inability to use the
 | 
				
			||||||
 | 
					      Work (including but not limited to damages for loss of goodwill,
 | 
				
			||||||
 | 
					      work stoppage, computer failure or malfunction, or any and all
 | 
				
			||||||
 | 
					      other commercial damages or losses), even if such Contributor
 | 
				
			||||||
 | 
					      has been advised of the possibility of such damages.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   9. Accepting Warranty or Additional Liability. While redistributing
 | 
				
			||||||
 | 
					      the Work or Derivative Works thereof, You may choose to offer,
 | 
				
			||||||
 | 
					      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
				
			||||||
 | 
					      or other liability obligations and/or rights consistent with this
 | 
				
			||||||
 | 
					      License. However, in accepting such obligations, You may act only
 | 
				
			||||||
 | 
					      on Your own behalf and on Your sole responsibility, not on behalf
 | 
				
			||||||
 | 
					      of any other Contributor, and only if You agree to indemnify,
 | 
				
			||||||
 | 
					      defend, and hold each Contributor harmless for any liability
 | 
				
			||||||
 | 
					      incurred by, or claims asserted against, such Contributor by reason
 | 
				
			||||||
 | 
					      of your accepting any such warranty or additional liability.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   END OF TERMS AND CONDITIONS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   APPENDIX: How to apply the Apache License to your work.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      To apply the Apache License to your work, attach the following
 | 
				
			||||||
 | 
					      boilerplate notice, with the fields enclosed by brackets "[]"
 | 
				
			||||||
 | 
					      replaced with your own identifying information. (Don't include
 | 
				
			||||||
 | 
					      the brackets!)  The text should be enclosed in the appropriate
 | 
				
			||||||
 | 
					      comment syntax for the file format. We also recommend that a
 | 
				
			||||||
 | 
					      file or class name and description of purpose be included on the
 | 
				
			||||||
 | 
					      same "printed page" as the copyright notice for easier
 | 
				
			||||||
 | 
					      identification within third-party archives.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Copyright [yyyy] [name of copyright owner]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					   you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					   You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					   distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					   See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					   limitations under the License.
 | 
				
			||||||
							
								
								
									
										276
									
								
								vendor/k8s.io/kube-openapi/pkg/aggregator/aggregator.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										276
									
								
								vendor/k8s.io/kube-openapi/pkg/aggregator/aggregator.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,276 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2017 The Kubernetes Authors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package aggregator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"reflect"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/go-openapi/spec"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"k8s.io/kube-openapi/pkg/util"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						definitionPrefix = "#/definitions/"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Run a walkRefCallback method on all references of an OpenAPI spec
 | 
				
			||||||
 | 
					type referenceWalker struct {
 | 
				
			||||||
 | 
						// walkRefCallback will be called on each reference and the return value
 | 
				
			||||||
 | 
						// will replace that reference. This will allow the callers to change
 | 
				
			||||||
 | 
						// all/some references of an spec (e.g. useful in renaming definitions).
 | 
				
			||||||
 | 
						walkRefCallback func(ref spec.Ref) spec.Ref
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// The spec to walk through.
 | 
				
			||||||
 | 
						root *spec.Swagger
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Keep track of visited references
 | 
				
			||||||
 | 
						alreadyVisited map[string]bool
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func walkOnAllReferences(walkRef func(ref spec.Ref) spec.Ref, sp *spec.Swagger) {
 | 
				
			||||||
 | 
						walker := &referenceWalker{walkRefCallback: walkRef, root: sp, alreadyVisited: map[string]bool{}}
 | 
				
			||||||
 | 
						walker.Start()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *referenceWalker) walkRef(ref spec.Ref) spec.Ref {
 | 
				
			||||||
 | 
						refStr := ref.String()
 | 
				
			||||||
 | 
						// References that start with #/definitions/ has a definition
 | 
				
			||||||
 | 
						// inside the same spec file. If that is the case, walk through
 | 
				
			||||||
 | 
						// those definitions too.
 | 
				
			||||||
 | 
						// We do not support external references yet.
 | 
				
			||||||
 | 
						if !s.alreadyVisited[refStr] && strings.HasPrefix(refStr, definitionPrefix) {
 | 
				
			||||||
 | 
							s.alreadyVisited[refStr] = true
 | 
				
			||||||
 | 
							def := s.root.Definitions[refStr[len(definitionPrefix):]]
 | 
				
			||||||
 | 
							s.walkSchema(&def)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s.walkRefCallback(ref)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *referenceWalker) walkSchema(schema *spec.Schema) {
 | 
				
			||||||
 | 
						if schema == nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						schema.Ref = s.walkRef(schema.Ref)
 | 
				
			||||||
 | 
						for _, v := range schema.Definitions {
 | 
				
			||||||
 | 
							s.walkSchema(&v)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, v := range schema.Properties {
 | 
				
			||||||
 | 
							s.walkSchema(&v)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, v := range schema.PatternProperties {
 | 
				
			||||||
 | 
							s.walkSchema(&v)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, v := range schema.AllOf {
 | 
				
			||||||
 | 
							s.walkSchema(&v)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, v := range schema.AnyOf {
 | 
				
			||||||
 | 
							s.walkSchema(&v)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, v := range schema.OneOf {
 | 
				
			||||||
 | 
							s.walkSchema(&v)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if schema.Not != nil {
 | 
				
			||||||
 | 
							s.walkSchema(schema.Not)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil {
 | 
				
			||||||
 | 
							s.walkSchema(schema.AdditionalProperties.Schema)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if schema.AdditionalItems != nil && schema.AdditionalItems.Schema != nil {
 | 
				
			||||||
 | 
							s.walkSchema(schema.AdditionalItems.Schema)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if schema.Items != nil {
 | 
				
			||||||
 | 
							if schema.Items.Schema != nil {
 | 
				
			||||||
 | 
								s.walkSchema(schema.Items.Schema)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for _, v := range schema.Items.Schemas {
 | 
				
			||||||
 | 
								s.walkSchema(&v)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *referenceWalker) walkParams(params []spec.Parameter) {
 | 
				
			||||||
 | 
						if params == nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, param := range params {
 | 
				
			||||||
 | 
							param.Ref = s.walkRef(param.Ref)
 | 
				
			||||||
 | 
							s.walkSchema(param.Schema)
 | 
				
			||||||
 | 
							if param.Items != nil {
 | 
				
			||||||
 | 
								param.Items.Ref = s.walkRef(param.Items.Ref)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *referenceWalker) walkResponse(resp *spec.Response) {
 | 
				
			||||||
 | 
						if resp == nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						resp.Ref = s.walkRef(resp.Ref)
 | 
				
			||||||
 | 
						s.walkSchema(resp.Schema)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *referenceWalker) walkOperation(op *spec.Operation) {
 | 
				
			||||||
 | 
						if op == nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						s.walkParams(op.Parameters)
 | 
				
			||||||
 | 
						if op.Responses == nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						s.walkResponse(op.Responses.Default)
 | 
				
			||||||
 | 
						for _, r := range op.Responses.StatusCodeResponses {
 | 
				
			||||||
 | 
							s.walkResponse(&r)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *referenceWalker) Start() {
 | 
				
			||||||
 | 
						for _, pathItem := range s.root.Paths.Paths {
 | 
				
			||||||
 | 
							s.walkParams(pathItem.Parameters)
 | 
				
			||||||
 | 
							s.walkOperation(pathItem.Delete)
 | 
				
			||||||
 | 
							s.walkOperation(pathItem.Get)
 | 
				
			||||||
 | 
							s.walkOperation(pathItem.Head)
 | 
				
			||||||
 | 
							s.walkOperation(pathItem.Options)
 | 
				
			||||||
 | 
							s.walkOperation(pathItem.Patch)
 | 
				
			||||||
 | 
							s.walkOperation(pathItem.Post)
 | 
				
			||||||
 | 
							s.walkOperation(pathItem.Put)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// FilterSpecByPaths remove unnecessary paths and unused definitions.
 | 
				
			||||||
 | 
					func FilterSpecByPaths(sp *spec.Swagger, keepPathPrefixes []string) {
 | 
				
			||||||
 | 
						// First remove unwanted paths
 | 
				
			||||||
 | 
						prefixes := util.NewTrie(keepPathPrefixes)
 | 
				
			||||||
 | 
						orgPaths := sp.Paths
 | 
				
			||||||
 | 
						if orgPaths == nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sp.Paths = &spec.Paths{
 | 
				
			||||||
 | 
							VendorExtensible: orgPaths.VendorExtensible,
 | 
				
			||||||
 | 
							Paths:            map[string]spec.PathItem{},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for path, pathItem := range orgPaths.Paths {
 | 
				
			||||||
 | 
							if !prefixes.HasPrefix(path) {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							sp.Paths.Paths[path] = pathItem
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Walk all references to find all definition references.
 | 
				
			||||||
 | 
						usedDefinitions := map[string]bool{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						walkOnAllReferences(func(ref spec.Ref) spec.Ref {
 | 
				
			||||||
 | 
							if ref.String() != "" {
 | 
				
			||||||
 | 
								refStr := ref.String()
 | 
				
			||||||
 | 
								if strings.HasPrefix(refStr, definitionPrefix) {
 | 
				
			||||||
 | 
									usedDefinitions[refStr[len(definitionPrefix):]] = true
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return ref
 | 
				
			||||||
 | 
						}, sp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Remove unused definitions
 | 
				
			||||||
 | 
						orgDefinitions := sp.Definitions
 | 
				
			||||||
 | 
						sp.Definitions = spec.Definitions{}
 | 
				
			||||||
 | 
						for k, v := range orgDefinitions {
 | 
				
			||||||
 | 
							if usedDefinitions[k] {
 | 
				
			||||||
 | 
								sp.Definitions[k] = v
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func renameDefinition(s *spec.Swagger, old, new string) {
 | 
				
			||||||
 | 
						old_ref := definitionPrefix + old
 | 
				
			||||||
 | 
						new_ref := definitionPrefix + new
 | 
				
			||||||
 | 
						walkOnAllReferences(func(ref spec.Ref) spec.Ref {
 | 
				
			||||||
 | 
							if ref.String() == old_ref {
 | 
				
			||||||
 | 
								return spec.MustCreateRef(new_ref)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return ref
 | 
				
			||||||
 | 
						}, s)
 | 
				
			||||||
 | 
						s.Definitions[new] = s.Definitions[old]
 | 
				
			||||||
 | 
						delete(s.Definitions, old)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Copy paths and definitions from source to dest, rename definitions if needed.
 | 
				
			||||||
 | 
					// dest will be mutated, and source will not be changed.
 | 
				
			||||||
 | 
					func MergeSpecs(dest, source *spec.Swagger) error {
 | 
				
			||||||
 | 
						sourceCopy, err := CloneSpec(source)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for k, v := range sourceCopy.Paths.Paths {
 | 
				
			||||||
 | 
							if _, found := dest.Paths.Paths[k]; found {
 | 
				
			||||||
 | 
								return fmt.Errorf("unable to merge: duplicated path %s", k)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							dest.Paths.Paths[k] = v
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						usedNames := map[string]bool{}
 | 
				
			||||||
 | 
						for k := range dest.Definitions {
 | 
				
			||||||
 | 
							usedNames[k] = true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						type Rename struct {
 | 
				
			||||||
 | 
							from, to string
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						renames := []Rename{}
 | 
				
			||||||
 | 
						for k, v := range sourceCopy.Definitions {
 | 
				
			||||||
 | 
							if usedNames[k] {
 | 
				
			||||||
 | 
								v2, found := dest.Definitions[k]
 | 
				
			||||||
 | 
								// Reuse model iff they are exactly the same.
 | 
				
			||||||
 | 
								if found && reflect.DeepEqual(v, v2) {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								i := 2
 | 
				
			||||||
 | 
								newName := fmt.Sprintf("%s_v%d", k, i)
 | 
				
			||||||
 | 
								_, foundInSource := sourceCopy.Definitions[newName]
 | 
				
			||||||
 | 
								for usedNames[newName] || foundInSource {
 | 
				
			||||||
 | 
									i += 1
 | 
				
			||||||
 | 
									newName = fmt.Sprintf("%s_v%d", k, i)
 | 
				
			||||||
 | 
									_, foundInSource = sourceCopy.Definitions[newName]
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								renames = append(renames, Rename{from: k, to: newName})
 | 
				
			||||||
 | 
								usedNames[newName] = true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, r := range renames {
 | 
				
			||||||
 | 
							renameDefinition(sourceCopy, r.from, r.to)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for k, v := range sourceCopy.Definitions {
 | 
				
			||||||
 | 
							if _, found := dest.Definitions[k]; !found {
 | 
				
			||||||
 | 
								dest.Definitions[k] = v
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Clone OpenAPI spec
 | 
				
			||||||
 | 
					func CloneSpec(source *spec.Swagger) (*spec.Swagger, error) {
 | 
				
			||||||
 | 
						// TODO(mehdy): Find a faster way to clone an spec
 | 
				
			||||||
 | 
						bytes, err := json.Marshal(source)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var ret spec.Swagger
 | 
				
			||||||
 | 
						err = json.Unmarshal(bytes, &ret)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &ret, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								vendor/k8s.io/kube-openapi/pkg/builder/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								vendor/k8s.io/kube-openapi/pkg/builder/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2016 The Kubernetes Authors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Package builder contains code to generate OpenAPI discovery spec (which
 | 
				
			||||||
 | 
					// initial version of it also known as Swagger 2.0).
 | 
				
			||||||
 | 
					// For more details: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md
 | 
				
			||||||
 | 
					package builder
 | 
				
			||||||
							
								
								
									
										424
									
								
								vendor/k8s.io/kube-openapi/pkg/builder/openapi.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										424
									
								
								vendor/k8s.io/kube-openapi/pkg/builder/openapi.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,424 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2016 The Kubernetes Authors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package builder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
						"reflect"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						restful "github.com/emicklei/go-restful"
 | 
				
			||||||
 | 
						"github.com/go-openapi/spec"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"k8s.io/kube-openapi/pkg/common"
 | 
				
			||||||
 | 
						"k8s.io/kube-openapi/pkg/util"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						OpenAPIVersion = "2.0"
 | 
				
			||||||
 | 
						// TODO: Make this configurable.
 | 
				
			||||||
 | 
						extensionPrefix = "x-kubernetes-"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type openAPI struct {
 | 
				
			||||||
 | 
						config       *common.Config
 | 
				
			||||||
 | 
						swagger      *spec.Swagger
 | 
				
			||||||
 | 
						protocolList []string
 | 
				
			||||||
 | 
						definitions  map[string]common.OpenAPIDefinition
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// BuildOpenAPISpec builds OpenAPI spec given a list of webservices (containing routes) and common.Config to customize it.
 | 
				
			||||||
 | 
					func BuildOpenAPISpec(webServices []*restful.WebService, config *common.Config) (*spec.Swagger, error) {
 | 
				
			||||||
 | 
						o := openAPI{
 | 
				
			||||||
 | 
							config: config,
 | 
				
			||||||
 | 
							swagger: &spec.Swagger{
 | 
				
			||||||
 | 
								SwaggerProps: spec.SwaggerProps{
 | 
				
			||||||
 | 
									Swagger:     OpenAPIVersion,
 | 
				
			||||||
 | 
									Definitions: spec.Definitions{},
 | 
				
			||||||
 | 
									Paths:       &spec.Paths{Paths: map[string]spec.PathItem{}},
 | 
				
			||||||
 | 
									Info:        config.Info,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err := o.init(webServices)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return o.swagger, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (o *openAPI) init(webServices []*restful.WebService) error {
 | 
				
			||||||
 | 
						if o.config.GetOperationIDAndTags == nil {
 | 
				
			||||||
 | 
							o.config.GetOperationIDAndTags = func(r *restful.Route) (string, []string, error) {
 | 
				
			||||||
 | 
								return r.Operation, nil, nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if o.config.GetDefinitionName == nil {
 | 
				
			||||||
 | 
							o.config.GetDefinitionName = func(name string) (string, spec.Extensions) {
 | 
				
			||||||
 | 
								return name[strings.LastIndex(name, "/")+1:], nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						o.definitions = o.config.GetDefinitions(func(name string) spec.Ref {
 | 
				
			||||||
 | 
							defName, _ := o.config.GetDefinitionName(name)
 | 
				
			||||||
 | 
							return spec.MustCreateRef("#/definitions/" + common.EscapeJsonPointer(defName))
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if o.config.CommonResponses == nil {
 | 
				
			||||||
 | 
							o.config.CommonResponses = map[int]spec.Response{}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						err := o.buildPaths(webServices)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if o.config.SecurityDefinitions != nil {
 | 
				
			||||||
 | 
							o.swagger.SecurityDefinitions = *o.config.SecurityDefinitions
 | 
				
			||||||
 | 
							o.swagger.Security = o.config.DefaultSecurity
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if o.config.PostProcessSpec != nil {
 | 
				
			||||||
 | 
							o.swagger, err = o.config.PostProcessSpec(o.swagger)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getCanonicalizeTypeName(t reflect.Type) string {
 | 
				
			||||||
 | 
						if t.PkgPath() == "" {
 | 
				
			||||||
 | 
							return t.Name()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						path := t.PkgPath()
 | 
				
			||||||
 | 
						if strings.Contains(path, "/vendor/") {
 | 
				
			||||||
 | 
							path = path[strings.Index(path, "/vendor/")+len("/vendor/"):]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return path + "." + t.Name()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (o *openAPI) buildDefinitionRecursively(name string) error {
 | 
				
			||||||
 | 
						uniqueName, extensions := o.config.GetDefinitionName(name)
 | 
				
			||||||
 | 
						if _, ok := o.swagger.Definitions[uniqueName]; ok {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if item, ok := o.definitions[name]; ok {
 | 
				
			||||||
 | 
							schema := spec.Schema{
 | 
				
			||||||
 | 
								VendorExtensible:   item.Schema.VendorExtensible,
 | 
				
			||||||
 | 
								SchemaProps:        item.Schema.SchemaProps,
 | 
				
			||||||
 | 
								SwaggerSchemaProps: item.Schema.SwaggerSchemaProps,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if extensions != nil {
 | 
				
			||||||
 | 
								if schema.Extensions == nil {
 | 
				
			||||||
 | 
									schema.Extensions = spec.Extensions{}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								for k, v := range extensions {
 | 
				
			||||||
 | 
									schema.Extensions[k] = v
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							o.swagger.Definitions[uniqueName] = schema
 | 
				
			||||||
 | 
							for _, v := range item.Dependencies {
 | 
				
			||||||
 | 
								if err := o.buildDefinitionRecursively(v); err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return fmt.Errorf("cannot find model definition for %v. If you added a new type, you may need to add +k8s:openapi-gen=true to the package or type and run code-gen again", name)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// buildDefinitionForType build a definition for a given type and return a referable name to it's definition.
 | 
				
			||||||
 | 
					// This is the main function that keep track of definitions used in this spec and is depend on code generated
 | 
				
			||||||
 | 
					// by k8s.io/kubernetes/cmd/libs/go2idl/openapi-gen.
 | 
				
			||||||
 | 
					func (o *openAPI) buildDefinitionForType(sample interface{}) (string, error) {
 | 
				
			||||||
 | 
						t := reflect.TypeOf(sample)
 | 
				
			||||||
 | 
						if t.Kind() == reflect.Ptr {
 | 
				
			||||||
 | 
							t = t.Elem()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						name := getCanonicalizeTypeName(t)
 | 
				
			||||||
 | 
						if err := o.buildDefinitionRecursively(name); err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defName, _ := o.config.GetDefinitionName(name)
 | 
				
			||||||
 | 
						return "#/definitions/" + common.EscapeJsonPointer(defName), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// buildPaths builds OpenAPI paths using go-restful's web services.
 | 
				
			||||||
 | 
					func (o *openAPI) buildPaths(webServices []*restful.WebService) error {
 | 
				
			||||||
 | 
						pathsToIgnore := util.NewTrie(o.config.IgnorePrefixes)
 | 
				
			||||||
 | 
						duplicateOpId := make(map[string]string)
 | 
				
			||||||
 | 
						for _, w := range webServices {
 | 
				
			||||||
 | 
							rootPath := w.RootPath()
 | 
				
			||||||
 | 
							if pathsToIgnore.HasPrefix(rootPath) {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							commonParams, err := o.buildParameters(w.PathParameters())
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for path, routes := range groupRoutesByPath(w.Routes()) {
 | 
				
			||||||
 | 
								// go-swagger has special variable definition {$NAME:*} that can only be
 | 
				
			||||||
 | 
								// used at the end of the path and it is not recognized by OpenAPI.
 | 
				
			||||||
 | 
								if strings.HasSuffix(path, ":*}") {
 | 
				
			||||||
 | 
									path = path[:len(path)-3] + "}"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if pathsToIgnore.HasPrefix(path) {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								// Aggregating common parameters make API spec (and generated clients) simpler
 | 
				
			||||||
 | 
								inPathCommonParamsMap, err := o.findCommonParameters(routes)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								pathItem, exists := o.swagger.Paths.Paths[path]
 | 
				
			||||||
 | 
								if exists {
 | 
				
			||||||
 | 
									return fmt.Errorf("duplicate webservice route has been found for path: %v", path)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								pathItem = spec.PathItem{
 | 
				
			||||||
 | 
									PathItemProps: spec.PathItemProps{
 | 
				
			||||||
 | 
										Parameters: make([]spec.Parameter, 0),
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								// add web services's parameters as well as any parameters appears in all ops, as common parameters
 | 
				
			||||||
 | 
								pathItem.Parameters = append(pathItem.Parameters, commonParams...)
 | 
				
			||||||
 | 
								for _, p := range inPathCommonParamsMap {
 | 
				
			||||||
 | 
									pathItem.Parameters = append(pathItem.Parameters, p)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								sortParameters(pathItem.Parameters)
 | 
				
			||||||
 | 
								for _, route := range routes {
 | 
				
			||||||
 | 
									op, err := o.buildOperations(route, inPathCommonParamsMap)
 | 
				
			||||||
 | 
									sortParameters(op.Parameters)
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										return err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									dpath, exists := duplicateOpId[op.ID]
 | 
				
			||||||
 | 
									if exists {
 | 
				
			||||||
 | 
										return fmt.Errorf("duplicate Operation ID %v for path %v and %v", op.ID, dpath, path)
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										duplicateOpId[op.ID] = path
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									switch strings.ToUpper(route.Method) {
 | 
				
			||||||
 | 
									case "GET":
 | 
				
			||||||
 | 
										pathItem.Get = op
 | 
				
			||||||
 | 
									case "POST":
 | 
				
			||||||
 | 
										pathItem.Post = op
 | 
				
			||||||
 | 
									case "HEAD":
 | 
				
			||||||
 | 
										pathItem.Head = op
 | 
				
			||||||
 | 
									case "PUT":
 | 
				
			||||||
 | 
										pathItem.Put = op
 | 
				
			||||||
 | 
									case "DELETE":
 | 
				
			||||||
 | 
										pathItem.Delete = op
 | 
				
			||||||
 | 
									case "OPTIONS":
 | 
				
			||||||
 | 
										pathItem.Options = op
 | 
				
			||||||
 | 
									case "PATCH":
 | 
				
			||||||
 | 
										pathItem.Patch = op
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								o.swagger.Paths.Paths[path] = pathItem
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// buildOperations builds operations for each webservice path
 | 
				
			||||||
 | 
					func (o *openAPI) buildOperations(route restful.Route, inPathCommonParamsMap map[interface{}]spec.Parameter) (ret *spec.Operation, err error) {
 | 
				
			||||||
 | 
						ret = &spec.Operation{
 | 
				
			||||||
 | 
							OperationProps: spec.OperationProps{
 | 
				
			||||||
 | 
								Description: route.Doc,
 | 
				
			||||||
 | 
								Consumes:    route.Consumes,
 | 
				
			||||||
 | 
								Produces:    route.Produces,
 | 
				
			||||||
 | 
								Schemes:     o.config.ProtocolList,
 | 
				
			||||||
 | 
								Responses: &spec.Responses{
 | 
				
			||||||
 | 
									ResponsesProps: spec.ResponsesProps{
 | 
				
			||||||
 | 
										StatusCodeResponses: make(map[int]spec.Response),
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for k, v := range route.Metadata {
 | 
				
			||||||
 | 
							if strings.HasPrefix(k, extensionPrefix) {
 | 
				
			||||||
 | 
								if ret.Extensions == nil {
 | 
				
			||||||
 | 
									ret.Extensions = spec.Extensions{}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								ret.Extensions.Add(k, v)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if ret.ID, ret.Tags, err = o.config.GetOperationIDAndTags(&route); err != nil {
 | 
				
			||||||
 | 
							return ret, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Build responses
 | 
				
			||||||
 | 
						for _, resp := range route.ResponseErrors {
 | 
				
			||||||
 | 
							ret.Responses.StatusCodeResponses[resp.Code], err = o.buildResponse(resp.Model, resp.Message)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return ret, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// If there is no response but a write sample, assume that write sample is an http.StatusOK response.
 | 
				
			||||||
 | 
						if len(ret.Responses.StatusCodeResponses) == 0 && route.WriteSample != nil {
 | 
				
			||||||
 | 
							ret.Responses.StatusCodeResponses[http.StatusOK], err = o.buildResponse(route.WriteSample, "OK")
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return ret, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for code, resp := range o.config.CommonResponses {
 | 
				
			||||||
 | 
							if _, exists := ret.Responses.StatusCodeResponses[code]; !exists {
 | 
				
			||||||
 | 
								ret.Responses.StatusCodeResponses[code] = resp
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// If there is still no response, use default response provided.
 | 
				
			||||||
 | 
						if len(ret.Responses.StatusCodeResponses) == 0 {
 | 
				
			||||||
 | 
							ret.Responses.Default = o.config.DefaultResponse
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Build non-common Parameters
 | 
				
			||||||
 | 
						ret.Parameters = make([]spec.Parameter, 0)
 | 
				
			||||||
 | 
						for _, param := range route.ParameterDocs {
 | 
				
			||||||
 | 
							if _, isCommon := inPathCommonParamsMap[mapKeyFromParam(param)]; !isCommon {
 | 
				
			||||||
 | 
								openAPIParam, err := o.buildParameter(param.Data(), route.ReadSample)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return ret, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								ret.Parameters = append(ret.Parameters, openAPIParam)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ret, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (o *openAPI) buildResponse(model interface{}, description string) (spec.Response, error) {
 | 
				
			||||||
 | 
						schema, err := o.toSchema(model)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return spec.Response{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return spec.Response{
 | 
				
			||||||
 | 
							ResponseProps: spec.ResponseProps{
 | 
				
			||||||
 | 
								Description: description,
 | 
				
			||||||
 | 
								Schema:      schema,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (o *openAPI) findCommonParameters(routes []restful.Route) (map[interface{}]spec.Parameter, error) {
 | 
				
			||||||
 | 
						commonParamsMap := make(map[interface{}]spec.Parameter, 0)
 | 
				
			||||||
 | 
						paramOpsCountByName := make(map[interface{}]int, 0)
 | 
				
			||||||
 | 
						paramNameKindToDataMap := make(map[interface{}]restful.ParameterData, 0)
 | 
				
			||||||
 | 
						for _, route := range routes {
 | 
				
			||||||
 | 
							routeParamDuplicateMap := make(map[interface{}]bool)
 | 
				
			||||||
 | 
							s := ""
 | 
				
			||||||
 | 
							for _, param := range route.ParameterDocs {
 | 
				
			||||||
 | 
								m, _ := json.Marshal(param.Data())
 | 
				
			||||||
 | 
								s += string(m) + "\n"
 | 
				
			||||||
 | 
								key := mapKeyFromParam(param)
 | 
				
			||||||
 | 
								if routeParamDuplicateMap[key] {
 | 
				
			||||||
 | 
									msg, _ := json.Marshal(route.ParameterDocs)
 | 
				
			||||||
 | 
									return commonParamsMap, fmt.Errorf("duplicate parameter %v for route %v, %v", param.Data().Name, string(msg), s)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								routeParamDuplicateMap[key] = true
 | 
				
			||||||
 | 
								paramOpsCountByName[key]++
 | 
				
			||||||
 | 
								paramNameKindToDataMap[key] = param.Data()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for key, count := range paramOpsCountByName {
 | 
				
			||||||
 | 
							paramData := paramNameKindToDataMap[key]
 | 
				
			||||||
 | 
							if count == len(routes) && paramData.Kind != restful.BodyParameterKind {
 | 
				
			||||||
 | 
								openAPIParam, err := o.buildParameter(paramData, nil)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return commonParamsMap, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								commonParamsMap[key] = openAPIParam
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return commonParamsMap, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (o *openAPI) toSchema(model interface{}) (_ *spec.Schema, err error) {
 | 
				
			||||||
 | 
						if openAPIType, openAPIFormat := common.GetOpenAPITypeFormat(getCanonicalizeTypeName(reflect.TypeOf(model))); openAPIType != "" {
 | 
				
			||||||
 | 
							return &spec.Schema{
 | 
				
			||||||
 | 
								SchemaProps: spec.SchemaProps{
 | 
				
			||||||
 | 
									Type:   []string{openAPIType},
 | 
				
			||||||
 | 
									Format: openAPIFormat,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							}, nil
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							ref, err := o.buildDefinitionForType(model)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return &spec.Schema{
 | 
				
			||||||
 | 
								SchemaProps: spec.SchemaProps{
 | 
				
			||||||
 | 
									Ref: spec.MustCreateRef(ref),
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							}, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (o *openAPI) buildParameter(restParam restful.ParameterData, bodySample interface{}) (ret spec.Parameter, err error) {
 | 
				
			||||||
 | 
						ret = spec.Parameter{
 | 
				
			||||||
 | 
							ParamProps: spec.ParamProps{
 | 
				
			||||||
 | 
								Name:        restParam.Name,
 | 
				
			||||||
 | 
								Description: restParam.Description,
 | 
				
			||||||
 | 
								Required:    restParam.Required,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						switch restParam.Kind {
 | 
				
			||||||
 | 
						case restful.BodyParameterKind:
 | 
				
			||||||
 | 
							if bodySample != nil {
 | 
				
			||||||
 | 
								ret.In = "body"
 | 
				
			||||||
 | 
								ret.Schema, err = o.toSchema(bodySample)
 | 
				
			||||||
 | 
								return ret, err
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								// There is not enough information in the body parameter to build the definition.
 | 
				
			||||||
 | 
								// Body parameter has a data type that is a short name but we need full package name
 | 
				
			||||||
 | 
								// of the type to create a definition.
 | 
				
			||||||
 | 
								return ret, fmt.Errorf("restful body parameters are not supported: %v", restParam.DataType)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						case restful.PathParameterKind:
 | 
				
			||||||
 | 
							ret.In = "path"
 | 
				
			||||||
 | 
							if !restParam.Required {
 | 
				
			||||||
 | 
								return ret, fmt.Errorf("path parameters should be marked at required for parameter %v", restParam)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						case restful.QueryParameterKind:
 | 
				
			||||||
 | 
							ret.In = "query"
 | 
				
			||||||
 | 
						case restful.HeaderParameterKind:
 | 
				
			||||||
 | 
							ret.In = "header"
 | 
				
			||||||
 | 
						case restful.FormParameterKind:
 | 
				
			||||||
 | 
							ret.In = "formData"
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return ret, fmt.Errorf("unknown restful operation kind : %v", restParam.Kind)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						openAPIType, openAPIFormat := common.GetOpenAPITypeFormat(restParam.DataType)
 | 
				
			||||||
 | 
						if openAPIType == "" {
 | 
				
			||||||
 | 
							return ret, fmt.Errorf("non-body Restful parameter type should be a simple type, but got : %v", restParam.DataType)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ret.Type = openAPIType
 | 
				
			||||||
 | 
						ret.Format = openAPIFormat
 | 
				
			||||||
 | 
						ret.UniqueItems = !restParam.AllowMultiple
 | 
				
			||||||
 | 
						return ret, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (o *openAPI) buildParameters(restParam []*restful.Parameter) (ret []spec.Parameter, err error) {
 | 
				
			||||||
 | 
						ret = make([]spec.Parameter, len(restParam))
 | 
				
			||||||
 | 
						for i, v := range restParam {
 | 
				
			||||||
 | 
							ret[i], err = o.buildParameter(v.Data(), nil)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return ret, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ret, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										61
									
								
								vendor/k8s.io/kube-openapi/pkg/builder/util.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								vendor/k8s.io/kube-openapi/pkg/builder/util.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2016 The Kubernetes Authors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package builder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"sort"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/emicklei/go-restful"
 | 
				
			||||||
 | 
						"github.com/go-openapi/spec"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type parameters []spec.Parameter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s parameters) Len() int      { return len(s) }
 | 
				
			||||||
 | 
					func (s parameters) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// byNameIn used in sorting parameters by Name and In fields.
 | 
				
			||||||
 | 
					type byNameIn struct {
 | 
				
			||||||
 | 
						parameters
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s byNameIn) Less(i, j int) bool {
 | 
				
			||||||
 | 
						return s.parameters[i].Name < s.parameters[j].Name || (s.parameters[i].Name == s.parameters[j].Name && s.parameters[i].In < s.parameters[j].In)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SortParameters sorts parameters by Name and In fields.
 | 
				
			||||||
 | 
					func sortParameters(p []spec.Parameter) {
 | 
				
			||||||
 | 
						sort.Sort(byNameIn{p})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func groupRoutesByPath(routes []restful.Route) map[string][]restful.Route {
 | 
				
			||||||
 | 
						pathToRoutes := make(map[string][]restful.Route)
 | 
				
			||||||
 | 
						for _, r := range routes {
 | 
				
			||||||
 | 
							pathToRoutes[r.Path] = append(pathToRoutes[r.Path], r)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return pathToRoutes
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func mapKeyFromParam(param *restful.Parameter) interface{} {
 | 
				
			||||||
 | 
						return struct {
 | 
				
			||||||
 | 
							Name string
 | 
				
			||||||
 | 
							Kind int
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							Name: param.Data().Name,
 | 
				
			||||||
 | 
							Kind: param.Data().Kind,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										167
									
								
								vendor/k8s.io/kube-openapi/pkg/common/common.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								vendor/k8s.io/kube-openapi/pkg/common/common.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,167 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2016 The Kubernetes Authors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package common
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/emicklei/go-restful"
 | 
				
			||||||
 | 
						"github.com/go-openapi/spec"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// OpenAPIDefinition describes single type. Normally these definitions are auto-generated using gen-openapi.
 | 
				
			||||||
 | 
					type OpenAPIDefinition struct {
 | 
				
			||||||
 | 
						Schema       spec.Schema
 | 
				
			||||||
 | 
						Dependencies []string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ReferenceCallback func(path string) spec.Ref
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// OpenAPIDefinitions is collection of all definitions.
 | 
				
			||||||
 | 
					type GetOpenAPIDefinitions func(ReferenceCallback) map[string]OpenAPIDefinition
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// OpenAPIDefinitionGetter gets openAPI definitions for a given type. If a type implements this interface,
 | 
				
			||||||
 | 
					// the definition returned by it will be used, otherwise the auto-generated definitions will be used. See
 | 
				
			||||||
 | 
					// GetOpenAPITypeFormat for more information about trade-offs of using this interface or GetOpenAPITypeFormat method when
 | 
				
			||||||
 | 
					// possible.
 | 
				
			||||||
 | 
					type OpenAPIDefinitionGetter interface {
 | 
				
			||||||
 | 
						OpenAPIDefinition() *OpenAPIDefinition
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type PathHandler interface {
 | 
				
			||||||
 | 
						Handle(path string, handler http.Handler)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Config is set of configuration for openAPI spec generation.
 | 
				
			||||||
 | 
					type Config struct {
 | 
				
			||||||
 | 
						// List of supported protocols such as https, http, etc.
 | 
				
			||||||
 | 
						ProtocolList []string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Info is general information about the API.
 | 
				
			||||||
 | 
						Info *spec.Info
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// DefaultResponse will be used if an operation does not have any responses listed. It
 | 
				
			||||||
 | 
						// will show up as ... "responses" : {"default" : $DefaultResponse} in the spec.
 | 
				
			||||||
 | 
						DefaultResponse *spec.Response
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// CommonResponses will be added as a response to all operation specs. This is a good place to add common
 | 
				
			||||||
 | 
						// responses such as authorization failed.
 | 
				
			||||||
 | 
						CommonResponses map[int]spec.Response
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// List of webservice's path prefixes to ignore
 | 
				
			||||||
 | 
						IgnorePrefixes []string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// OpenAPIDefinitions should provide definition for all models used by routes. Failure to provide this map
 | 
				
			||||||
 | 
						// or any of the models will result in spec generation failure.
 | 
				
			||||||
 | 
						GetDefinitions GetOpenAPIDefinitions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// GetOperationIDAndTags returns operation id and tags for a restful route. It is an optional function to customize operation IDs.
 | 
				
			||||||
 | 
						GetOperationIDAndTags func(r *restful.Route) (string, []string, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// GetDefinitionName returns a friendly name for a definition base on the serving path. parameter `name` is the full name of the definition.
 | 
				
			||||||
 | 
						// It is an optional function to customize model names.
 | 
				
			||||||
 | 
						GetDefinitionName func(name string) (string, spec.Extensions)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// PostProcessSpec runs after the spec is ready to serve. It allows a final modification to the spec before serving.
 | 
				
			||||||
 | 
						PostProcessSpec func(*spec.Swagger) (*spec.Swagger, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// SecurityDefinitions is list of all security definitions for OpenAPI service. If this is not nil, the user of config
 | 
				
			||||||
 | 
						// is responsible to provide DefaultSecurity and (maybe) add unauthorized response to CommonResponses.
 | 
				
			||||||
 | 
						SecurityDefinitions *spec.SecurityDefinitions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// DefaultSecurity for all operations. This will pass as spec.SwaggerProps.Security to OpenAPI.
 | 
				
			||||||
 | 
						// For most cases, this will be list of acceptable definitions in SecurityDefinitions.
 | 
				
			||||||
 | 
						DefaultSecurity []map[string][]string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This function is a reference for converting go (or any custom type) to a simple open API type,format pair. There are
 | 
				
			||||||
 | 
					// two ways to customize spec for a type. If you add it here, a type will be converted to a simple type and the type
 | 
				
			||||||
 | 
					// comment (the comment that is added before type definition) will be lost. The spec will still have the property
 | 
				
			||||||
 | 
					// comment. The second way is to implement OpenAPIDefinitionGetter interface. That function can customize the spec (so
 | 
				
			||||||
 | 
					// the spec does not need to be simple type,format) or can even return a simple type,format (e.g. IntOrString). For simple
 | 
				
			||||||
 | 
					// type formats, the benefit of adding OpenAPIDefinitionGetter interface is to keep both type and property documentation.
 | 
				
			||||||
 | 
					// Example:
 | 
				
			||||||
 | 
					// type Sample struct {
 | 
				
			||||||
 | 
					//      ...
 | 
				
			||||||
 | 
					//      // port of the server
 | 
				
			||||||
 | 
					//      port IntOrString
 | 
				
			||||||
 | 
					//      ...
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					// // IntOrString documentation...
 | 
				
			||||||
 | 
					// type IntOrString { ... }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Adding IntOrString to this function:
 | 
				
			||||||
 | 
					// "port" : {
 | 
				
			||||||
 | 
					//           format:      "string",
 | 
				
			||||||
 | 
					//           type:        "int-or-string",
 | 
				
			||||||
 | 
					//           Description: "port of the server"
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Implement OpenAPIDefinitionGetter for IntOrString:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// "port" : {
 | 
				
			||||||
 | 
					//           $Ref:    "#/definitions/IntOrString"
 | 
				
			||||||
 | 
					//           Description: "port of the server"
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					// ...
 | 
				
			||||||
 | 
					// definitions:
 | 
				
			||||||
 | 
					// {
 | 
				
			||||||
 | 
					//           "IntOrString": {
 | 
				
			||||||
 | 
					//                     format:      "string",
 | 
				
			||||||
 | 
					//                     type:        "int-or-string",
 | 
				
			||||||
 | 
					//                     Description: "IntOrString documentation..."    // new
 | 
				
			||||||
 | 
					//           }
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					func GetOpenAPITypeFormat(typeName string) (string, string) {
 | 
				
			||||||
 | 
						schemaTypeFormatMap := map[string][]string{
 | 
				
			||||||
 | 
							"uint":        {"integer", "int32"},
 | 
				
			||||||
 | 
							"uint8":       {"integer", "byte"},
 | 
				
			||||||
 | 
							"uint16":      {"integer", "int32"},
 | 
				
			||||||
 | 
							"uint32":      {"integer", "int64"},
 | 
				
			||||||
 | 
							"uint64":      {"integer", "int64"},
 | 
				
			||||||
 | 
							"int":         {"integer", "int32"},
 | 
				
			||||||
 | 
							"int8":        {"integer", "byte"},
 | 
				
			||||||
 | 
							"int16":       {"integer", "int32"},
 | 
				
			||||||
 | 
							"int32":       {"integer", "int32"},
 | 
				
			||||||
 | 
							"int64":       {"integer", "int64"},
 | 
				
			||||||
 | 
							"byte":        {"integer", "byte"},
 | 
				
			||||||
 | 
							"float64":     {"number", "double"},
 | 
				
			||||||
 | 
							"float32":     {"number", "float"},
 | 
				
			||||||
 | 
							"bool":        {"boolean", ""},
 | 
				
			||||||
 | 
							"time.Time":   {"string", "date-time"},
 | 
				
			||||||
 | 
							"string":      {"string", ""},
 | 
				
			||||||
 | 
							"integer":     {"integer", ""},
 | 
				
			||||||
 | 
							"number":      {"number", ""},
 | 
				
			||||||
 | 
							"boolean":     {"boolean", ""},
 | 
				
			||||||
 | 
							"[]byte":      {"string", "byte"}, // base64 encoded characters
 | 
				
			||||||
 | 
							"interface{}": {"object", ""},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						mapped, ok := schemaTypeFormatMap[typeName]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return "", ""
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return mapped[0], mapped[1]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func EscapeJsonPointer(p string) string {
 | 
				
			||||||
 | 
						// Escaping reference name using rfc6901
 | 
				
			||||||
 | 
						p = strings.Replace(p, "~", "~0", -1)
 | 
				
			||||||
 | 
						p = strings.Replace(p, "/", "~1", -1)
 | 
				
			||||||
 | 
						return p
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										19
									
								
								vendor/k8s.io/kube-openapi/pkg/common/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								vendor/k8s.io/kube-openapi/pkg/common/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2016 The Kubernetes Authors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// package common holds shared code and types between open API code
 | 
				
			||||||
 | 
					// generator and spec generator.
 | 
				
			||||||
 | 
					package common
 | 
				
			||||||
							
								
								
									
										15
									
								
								vendor/k8s.io/kube-openapi/pkg/generators/README
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/k8s.io/kube-openapi/pkg/generators/README
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					# Generate OpenAPI definitions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- 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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# 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 used to pass more information to client generators or
 | 
				
			||||||
 | 
					documentation generators. For example a type might have a friendly name to be displayed in documentation or
 | 
				
			||||||
 | 
					being used in a client's fluent interface.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TODO(mehdy): Make k8s:openapi-gen a parameter to the generator now that OpenAPI has its own repo.
 | 
				
			||||||
							
								
								
									
										612
									
								
								vendor/k8s.io/kube-openapi/pkg/generators/openapi.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										612
									
								
								vendor/k8s.io/kube-openapi/pkg/generators/openapi.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,612 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2016 The Kubernetes Authors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package generators
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
						"path/filepath"
 | 
				
			||||||
 | 
						"reflect"
 | 
				
			||||||
 | 
						"sort"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"k8s.io/gengo/args"
 | 
				
			||||||
 | 
						"k8s.io/gengo/generator"
 | 
				
			||||||
 | 
						"k8s.io/gengo/namer"
 | 
				
			||||||
 | 
						"k8s.io/gengo/types"
 | 
				
			||||||
 | 
						openapi "k8s.io/kube-openapi/pkg/common"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/golang/glog"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This is the comment tag that carries parameters for open API generation.
 | 
				
			||||||
 | 
					const tagName = "k8s:openapi-gen"
 | 
				
			||||||
 | 
					const tagOptional = "optional"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Known values for the tag.
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						tagValueTrue               = "true"
 | 
				
			||||||
 | 
						tagValueFalse              = "false"
 | 
				
			||||||
 | 
						tagExtensionPrefix         = "x-kubernetes-"
 | 
				
			||||||
 | 
						tagPatchStrategy           = "patchStrategy"
 | 
				
			||||||
 | 
						tagPatchMergeKey           = "patchMergeKey"
 | 
				
			||||||
 | 
						patchStrategyExtensionName = "patch-strategy"
 | 
				
			||||||
 | 
						patchMergeKeyExtensionName = "patch-merge-key"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getOpenAPITagValue(comments []string) []string {
 | 
				
			||||||
 | 
						return types.ExtractCommentTags("+", comments)[tagName]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getSingleTagsValue(comments []string, tag string) (string, error) {
 | 
				
			||||||
 | 
						tags, ok := types.ExtractCommentTags("+", comments)[tag]
 | 
				
			||||||
 | 
						if !ok || len(tags) == 0 {
 | 
				
			||||||
 | 
							return "", nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(tags) > 1 {
 | 
				
			||||||
 | 
							return "", fmt.Errorf("multiple values are not allowed for tag %s", tag)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return tags[0], nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func hasOpenAPITagValue(comments []string, value string) bool {
 | 
				
			||||||
 | 
						tagValues := getOpenAPITagValue(comments)
 | 
				
			||||||
 | 
						for _, val := range tagValues {
 | 
				
			||||||
 | 
							if val == value {
 | 
				
			||||||
 | 
								return true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// hasOptionalTag returns true if the member has +optional in its comments or
 | 
				
			||||||
 | 
					// omitempty in its json tags.
 | 
				
			||||||
 | 
					func hasOptionalTag(m *types.Member) bool {
 | 
				
			||||||
 | 
						hasOptionalCommentTag := types.ExtractCommentTags(
 | 
				
			||||||
 | 
							"+", m.CommentLines)[tagOptional] != nil
 | 
				
			||||||
 | 
						hasOptionalJsonTag := strings.Contains(
 | 
				
			||||||
 | 
							reflect.StructTag(m.Tags).Get("json"), "omitempty")
 | 
				
			||||||
 | 
						return hasOptionalCommentTag || hasOptionalJsonTag
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type identityNamer struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_ identityNamer) Name(t *types.Type) string {
 | 
				
			||||||
 | 
						return t.Name.String()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var _ namer.Namer = identityNamer{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NameSystems returns the name system used by the generators in this package.
 | 
				
			||||||
 | 
					func NameSystems() namer.NameSystems {
 | 
				
			||||||
 | 
						return namer.NameSystems{
 | 
				
			||||||
 | 
							"raw":           namer.NewRawNamer("", nil),
 | 
				
			||||||
 | 
							"sorting_namer": identityNamer{},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DefaultNameSystem returns the default name system for ordering the types to be
 | 
				
			||||||
 | 
					// processed by the generators in this package.
 | 
				
			||||||
 | 
					func DefaultNameSystem() string {
 | 
				
			||||||
 | 
						return "sorting_namer"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages {
 | 
				
			||||||
 | 
						boilerplate, err := arguments.LoadGoBoilerplate()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Fatalf("Failed loading boilerplate: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						header := append([]byte(fmt.Sprintf("// +build !%s\n\n", arguments.GeneratedBuildTag)), boilerplate...)
 | 
				
			||||||
 | 
						header = append(header, []byte(
 | 
				
			||||||
 | 
							`
 | 
				
			||||||
 | 
					// This file was autogenerated by openapi-gen. Do not edit it manually!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`)...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := context.AddDir(arguments.OutputPackagePath); err != nil {
 | 
				
			||||||
 | 
							glog.Fatalf("Failed to load output package: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						pkg := context.Universe[arguments.OutputPackagePath]
 | 
				
			||||||
 | 
						if pkg == nil {
 | 
				
			||||||
 | 
							glog.Fatalf("Got nil output package: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return generator.Packages{
 | 
				
			||||||
 | 
							&generator.DefaultPackage{
 | 
				
			||||||
 | 
								PackageName: strings.Split(filepath.Base(pkg.Path), ".")[0],
 | 
				
			||||||
 | 
								PackagePath: pkg.Path,
 | 
				
			||||||
 | 
								HeaderText:  header,
 | 
				
			||||||
 | 
								GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) {
 | 
				
			||||||
 | 
									return []generator.Generator{NewOpenAPIGen(arguments.OutputFileBaseName, pkg, context)}
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								FilterFunc: func(c *generator.Context, t *types.Type) bool {
 | 
				
			||||||
 | 
									// There is a conflict between this codegen and codecgen, we should avoid types generated for codecgen
 | 
				
			||||||
 | 
									if strings.HasPrefix(t.Name.Name, "codecSelfer") {
 | 
				
			||||||
 | 
										return false
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									pkg := context.Universe.Package(t.Name.Package)
 | 
				
			||||||
 | 
									if hasOpenAPITagValue(pkg.Comments, tagValueTrue) {
 | 
				
			||||||
 | 
										return !hasOpenAPITagValue(t.CommentLines, tagValueFalse)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if hasOpenAPITagValue(t.CommentLines, tagValueTrue) {
 | 
				
			||||||
 | 
										return true
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									return false
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						specPackagePath          = "github.com/go-openapi/spec"
 | 
				
			||||||
 | 
						openAPICommonPackagePath = "k8s.io/kube-openapi/pkg/common"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// openApiGen produces a file with auto-generated OpenAPI functions.
 | 
				
			||||||
 | 
					type openAPIGen struct {
 | 
				
			||||||
 | 
						generator.DefaultGen
 | 
				
			||||||
 | 
						// TargetPackage is the package that will get GetOpenAPIDefinitions function returns all open API definitions.
 | 
				
			||||||
 | 
						targetPackage *types.Package
 | 
				
			||||||
 | 
						imports       namer.ImportTracker
 | 
				
			||||||
 | 
						context       *generator.Context
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewOpenAPIGen(sanitizedName string, targetPackage *types.Package, context *generator.Context) generator.Generator {
 | 
				
			||||||
 | 
						return &openAPIGen{
 | 
				
			||||||
 | 
							DefaultGen: generator.DefaultGen{
 | 
				
			||||||
 | 
								OptionalName: sanitizedName,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							imports:       generator.NewImportTracker(),
 | 
				
			||||||
 | 
							targetPackage: targetPackage,
 | 
				
			||||||
 | 
							context:       context,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (g *openAPIGen) Namers(c *generator.Context) namer.NameSystems {
 | 
				
			||||||
 | 
						// Have the raw namer for this file track what it imports.
 | 
				
			||||||
 | 
						return namer.NameSystems{
 | 
				
			||||||
 | 
							"raw": namer.NewRawNamer(g.targetPackage.Path, g.imports),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (g *openAPIGen) Filter(c *generator.Context, t *types.Type) bool {
 | 
				
			||||||
 | 
						// There is a conflict between this codegen and codecgen, we should avoid types generated for codecgen
 | 
				
			||||||
 | 
						if strings.HasPrefix(t.Name.Name, "codecSelfer") {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (g *openAPIGen) isOtherPackage(pkg string) bool {
 | 
				
			||||||
 | 
						if pkg == g.targetPackage.Path {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if strings.HasSuffix(pkg, "\""+g.targetPackage.Path+"\"") {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (g *openAPIGen) Imports(c *generator.Context) []string {
 | 
				
			||||||
 | 
						importLines := []string{}
 | 
				
			||||||
 | 
						for _, singleImport := range g.imports.ImportLines() {
 | 
				
			||||||
 | 
							importLines = append(importLines, singleImport)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return importLines
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func argsFromType(t *types.Type) generator.Args {
 | 
				
			||||||
 | 
						return generator.Args{
 | 
				
			||||||
 | 
							"type":              t,
 | 
				
			||||||
 | 
							"ReferenceCallback": types.Ref(openAPICommonPackagePath, "ReferenceCallback"),
 | 
				
			||||||
 | 
							"OpenAPIDefinition": types.Ref(openAPICommonPackagePath, "OpenAPIDefinition"),
 | 
				
			||||||
 | 
							"SpecSchemaType":    types.Ref(specPackagePath, "Schema"),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (g *openAPIGen) Init(c *generator.Context, w io.Writer) error {
 | 
				
			||||||
 | 
						sw := generator.NewSnippetWriter(w, c, "$", "$")
 | 
				
			||||||
 | 
						sw.Do("func GetOpenAPIDefinitions(ref $.ReferenceCallback|raw$) map[string]$.OpenAPIDefinition|raw$ {\n", argsFromType(nil))
 | 
				
			||||||
 | 
						sw.Do("return map[string]$.OpenAPIDefinition|raw${\n", argsFromType(nil))
 | 
				
			||||||
 | 
						return sw.Error()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (g *openAPIGen) Finalize(c *generator.Context, w io.Writer) error {
 | 
				
			||||||
 | 
						sw := generator.NewSnippetWriter(w, c, "$", "$")
 | 
				
			||||||
 | 
						sw.Do("}\n", nil)
 | 
				
			||||||
 | 
						sw.Do("}\n", nil)
 | 
				
			||||||
 | 
						return sw.Error()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (g *openAPIGen) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
 | 
				
			||||||
 | 
						glog.V(5).Infof("generating for type %v", t)
 | 
				
			||||||
 | 
						sw := generator.NewSnippetWriter(w, c, "$", "$")
 | 
				
			||||||
 | 
						err := newOpenAPITypeWriter(sw).generate(t)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return sw.Error()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getJsonTags(m *types.Member) []string {
 | 
				
			||||||
 | 
						jsonTag := reflect.StructTag(m.Tags).Get("json")
 | 
				
			||||||
 | 
						if jsonTag == "" {
 | 
				
			||||||
 | 
							return []string{}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return strings.Split(jsonTag, ",")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getPatchTags(m *types.Member) (string, string) {
 | 
				
			||||||
 | 
						return reflect.StructTag(m.Tags).Get(tagPatchMergeKey), reflect.StructTag(m.Tags).Get(tagPatchStrategy)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getReferableName(m *types.Member) string {
 | 
				
			||||||
 | 
						jsonTags := getJsonTags(m)
 | 
				
			||||||
 | 
						if len(jsonTags) > 0 {
 | 
				
			||||||
 | 
							if jsonTags[0] == "-" {
 | 
				
			||||||
 | 
								return ""
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								return jsonTags[0]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return m.Name
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func shouldInlineMembers(m *types.Member) bool {
 | 
				
			||||||
 | 
						jsonTags := getJsonTags(m)
 | 
				
			||||||
 | 
						return len(jsonTags) > 1 && jsonTags[1] == "inline"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type openAPITypeWriter struct {
 | 
				
			||||||
 | 
						*generator.SnippetWriter
 | 
				
			||||||
 | 
						refTypes               map[string]*types.Type
 | 
				
			||||||
 | 
						GetDefinitionInterface *types.Type
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func newOpenAPITypeWriter(sw *generator.SnippetWriter) openAPITypeWriter {
 | 
				
			||||||
 | 
						return openAPITypeWriter{
 | 
				
			||||||
 | 
							SnippetWriter: sw,
 | 
				
			||||||
 | 
							refTypes:      map[string]*types.Type{},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func hasOpenAPIDefinitionMethod(t *types.Type) bool {
 | 
				
			||||||
 | 
						for mn, mt := range t.Methods {
 | 
				
			||||||
 | 
							if mn != "OpenAPIDefinition" {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if len(mt.Signature.Parameters) != 0 || len(mt.Signature.Results) != 1 {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							r := mt.Signature.Results[0]
 | 
				
			||||||
 | 
							if r.Name.Name != "OpenAPIDefinition" || r.Name.Package != openAPICommonPackagePath {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// typeShortName returns short package name (e.g. the name x appears in package x definition) dot type name.
 | 
				
			||||||
 | 
					func typeShortName(t *types.Type) string {
 | 
				
			||||||
 | 
						return filepath.Base(t.Name.Package) + "." + t.Name.Name
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (g openAPITypeWriter) generateMembers(t *types.Type, required []string) ([]string, error) {
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						for _, m := range t.Members {
 | 
				
			||||||
 | 
							if hasOpenAPITagValue(m.CommentLines, tagValueFalse) {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if shouldInlineMembers(&m) {
 | 
				
			||||||
 | 
								required, err = g.generateMembers(m.Type, required)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return required, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							name := getReferableName(&m)
 | 
				
			||||||
 | 
							if name == "" {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if !hasOptionalTag(&m) {
 | 
				
			||||||
 | 
								required = append(required, name)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if err = g.generateProperty(&m, t); err != nil {
 | 
				
			||||||
 | 
								return required, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return required, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (g openAPITypeWriter) generate(t *types.Type) error {
 | 
				
			||||||
 | 
						// Only generate for struct type and ignore the rest
 | 
				
			||||||
 | 
						switch t.Kind {
 | 
				
			||||||
 | 
						case types.Struct:
 | 
				
			||||||
 | 
							args := argsFromType(t)
 | 
				
			||||||
 | 
							g.Do("\"$.$\": ", t.Name)
 | 
				
			||||||
 | 
							if hasOpenAPIDefinitionMethod(t) {
 | 
				
			||||||
 | 
								g.Do("$.type|raw${}.OpenAPIDefinition(),\n", args)
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							g.Do("{\nSchema: spec.Schema{\nSchemaProps: spec.SchemaProps{\n", nil)
 | 
				
			||||||
 | 
							g.generateDescription(t.CommentLines)
 | 
				
			||||||
 | 
							g.Do("Properties: map[string]$.SpecSchemaType|raw${\n", args)
 | 
				
			||||||
 | 
							required, err := g.generateMembers(t, []string{})
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							g.Do("},\n", nil)
 | 
				
			||||||
 | 
							if len(required) > 0 {
 | 
				
			||||||
 | 
								g.Do("Required: []string{\"$.$\"},\n", strings.Join(required, "\",\""))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							g.Do("},\n", nil)
 | 
				
			||||||
 | 
							if err := g.generateExtensions(t.CommentLines); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							g.Do("},\n", nil)
 | 
				
			||||||
 | 
							g.Do("Dependencies: []string{\n", args)
 | 
				
			||||||
 | 
							// Map order is undefined, sort them or we may get a different file generated each time.
 | 
				
			||||||
 | 
							keys := []string{}
 | 
				
			||||||
 | 
							for k := range g.refTypes {
 | 
				
			||||||
 | 
								keys = append(keys, k)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							sort.Strings(keys)
 | 
				
			||||||
 | 
							for _, k := range keys {
 | 
				
			||||||
 | 
								v := g.refTypes[k]
 | 
				
			||||||
 | 
								if t, _ := openapi.GetOpenAPITypeFormat(v.String()); t != "" {
 | 
				
			||||||
 | 
									// This is a known type, we do not need a reference to it
 | 
				
			||||||
 | 
									// Will eliminate special case of time.Time
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								g.Do("\"$.$\",", k)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							g.Do("},\n},\n", nil)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (g openAPITypeWriter) generateExtensions(CommentLines []string) error {
 | 
				
			||||||
 | 
						tagValues := getOpenAPITagValue(CommentLines)
 | 
				
			||||||
 | 
						type NameValue struct {
 | 
				
			||||||
 | 
							Name, Value string
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						extensions := []NameValue{}
 | 
				
			||||||
 | 
						for _, val := range tagValues {
 | 
				
			||||||
 | 
							if strings.HasPrefix(val, tagExtensionPrefix) {
 | 
				
			||||||
 | 
								parts := strings.SplitN(val, ":", 2)
 | 
				
			||||||
 | 
								if len(parts) != 2 {
 | 
				
			||||||
 | 
									return fmt.Errorf("invalid extension value: %v", val)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								extensions = append(extensions, NameValue{parts[0], parts[1]})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						patchMergeKeyTag, err := getSingleTagsValue(CommentLines, tagPatchMergeKey)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(patchMergeKeyTag) > 0 {
 | 
				
			||||||
 | 
							extensions = append(extensions, NameValue{tagExtensionPrefix + patchMergeKeyExtensionName, patchMergeKeyTag})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						patchStrategyTag, err := getSingleTagsValue(CommentLines, tagPatchStrategy)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(patchStrategyTag) > 0 {
 | 
				
			||||||
 | 
							extensions = append(extensions, NameValue{tagExtensionPrefix + patchStrategyExtensionName, patchStrategyTag})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(extensions) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						g.Do("VendorExtensible: spec.VendorExtensible{\nExtensions: spec.Extensions{\n", nil)
 | 
				
			||||||
 | 
						for _, extension := range extensions {
 | 
				
			||||||
 | 
							g.Do("\"$.$\": ", extension.Name)
 | 
				
			||||||
 | 
							g.Do("\"$.$\",\n", extension.Value)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						g.Do("},\n},\n", nil)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO(#44005): Move this validation outside of this generator (probably to policy verifier)
 | 
				
			||||||
 | 
					func (g openAPITypeWriter) validatePatchTags(m *types.Member, parent *types.Type) error {
 | 
				
			||||||
 | 
						patchMergeKeyStructTag, patchStrategyStructTag := getPatchTags(m)
 | 
				
			||||||
 | 
						patchMergeKeyCommentTag, err := getSingleTagsValue(m.CommentLines, tagPatchMergeKey)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						patchStrategyCommentTag, err := getSingleTagsValue(m.CommentLines, tagPatchStrategy)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if patchMergeKeyStructTag != patchMergeKeyCommentTag {
 | 
				
			||||||
 | 
							return fmt.Errorf("patchMergeKey in comment and struct tags should match for member (%s) of (%s)",
 | 
				
			||||||
 | 
								m.Name, parent.Name.String())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if patchStrategyStructTag != patchStrategyCommentTag {
 | 
				
			||||||
 | 
							return fmt.Errorf("patchStrategy in comment and struct tags should match for member (%s) of (%s)",
 | 
				
			||||||
 | 
								m.Name, parent.Name.String())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (g openAPITypeWriter) generateDescription(CommentLines []string) {
 | 
				
			||||||
 | 
						var buffer bytes.Buffer
 | 
				
			||||||
 | 
						delPrevChar := func() {
 | 
				
			||||||
 | 
							if buffer.Len() > 0 {
 | 
				
			||||||
 | 
								buffer.Truncate(buffer.Len() - 1) // Delete the last " " or "\n"
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, line := range CommentLines {
 | 
				
			||||||
 | 
							// Ignore all lines after ---
 | 
				
			||||||
 | 
							if line == "---" {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							line = strings.TrimRight(line, " ")
 | 
				
			||||||
 | 
							leading := strings.TrimLeft(line, " ")
 | 
				
			||||||
 | 
							switch {
 | 
				
			||||||
 | 
							case len(line) == 0: // Keep paragraphs
 | 
				
			||||||
 | 
								delPrevChar()
 | 
				
			||||||
 | 
								buffer.WriteString("\n\n")
 | 
				
			||||||
 | 
							case strings.HasPrefix(leading, "TODO"): // Ignore one line TODOs
 | 
				
			||||||
 | 
							case strings.HasPrefix(leading, "+"): // Ignore instructions to go2idl
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								if strings.HasPrefix(line, " ") || strings.HasPrefix(line, "\t") {
 | 
				
			||||||
 | 
									delPrevChar()
 | 
				
			||||||
 | 
									line = "\n" + line + "\n" // Replace it with newline. This is useful when we have a line with: "Example:\n\tJSON-someting..."
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									line += " "
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								buffer.WriteString(line)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						postDoc := strings.TrimRight(buffer.String(), "\n")
 | 
				
			||||||
 | 
						postDoc = strings.Replace(postDoc, "\\\"", "\"", -1) // replace user's \" to "
 | 
				
			||||||
 | 
						postDoc = strings.Replace(postDoc, "\"", "\\\"", -1) // Escape "
 | 
				
			||||||
 | 
						postDoc = strings.Replace(postDoc, "\n", "\\n", -1)
 | 
				
			||||||
 | 
						postDoc = strings.Replace(postDoc, "\t", "\\t", -1)
 | 
				
			||||||
 | 
						postDoc = strings.Trim(postDoc, " ")
 | 
				
			||||||
 | 
						if postDoc != "" {
 | 
				
			||||||
 | 
							g.Do("Description: \"$.$\",\n", postDoc)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (g openAPITypeWriter) generateProperty(m *types.Member, parent *types.Type) error {
 | 
				
			||||||
 | 
						name := getReferableName(m)
 | 
				
			||||||
 | 
						if name == "" {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err := g.validatePatchTags(m, parent); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						g.Do("\"$.$\": {\n", name)
 | 
				
			||||||
 | 
						if err := g.generateExtensions(m.CommentLines); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						g.Do("SchemaProps: spec.SchemaProps{\n", nil)
 | 
				
			||||||
 | 
						g.generateDescription(m.CommentLines)
 | 
				
			||||||
 | 
						jsonTags := getJsonTags(m)
 | 
				
			||||||
 | 
						if len(jsonTags) > 1 && jsonTags[1] == "string" {
 | 
				
			||||||
 | 
							g.generateSimpleProperty("string", "")
 | 
				
			||||||
 | 
							g.Do("},\n},\n", nil)
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t := resolveAliasAndPtrType(m.Type)
 | 
				
			||||||
 | 
						// If we can get a openAPI type and format for this type, we consider it to be simple property
 | 
				
			||||||
 | 
						typeString, format := openapi.GetOpenAPITypeFormat(t.String())
 | 
				
			||||||
 | 
						if typeString != "" {
 | 
				
			||||||
 | 
							g.generateSimpleProperty(typeString, format)
 | 
				
			||||||
 | 
							g.Do("},\n},\n", nil)
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						switch t.Kind {
 | 
				
			||||||
 | 
						case types.Builtin:
 | 
				
			||||||
 | 
							return fmt.Errorf("please add type %v to getOpenAPITypeFormat function", t)
 | 
				
			||||||
 | 
						case types.Map:
 | 
				
			||||||
 | 
							if err := g.generateMapProperty(t); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						case types.Slice, types.Array:
 | 
				
			||||||
 | 
							if err := g.generateSliceProperty(t); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						case types.Struct, types.Interface:
 | 
				
			||||||
 | 
							g.generateReferenceProperty(t)
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return fmt.Errorf("cannot generate spec for type %v", t)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						g.Do("},\n},\n", nil)
 | 
				
			||||||
 | 
						return g.Error()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (g openAPITypeWriter) generateSimpleProperty(typeString, format string) {
 | 
				
			||||||
 | 
						g.Do("Type: []string{\"$.$\"},\n", typeString)
 | 
				
			||||||
 | 
						g.Do("Format: \"$.$\",\n", format)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (g openAPITypeWriter) generateReferenceProperty(t *types.Type) {
 | 
				
			||||||
 | 
						g.refTypes[t.Name.String()] = t
 | 
				
			||||||
 | 
						g.Do("Ref: ref(\"$.$\"),\n", t.Name.String())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func resolveAliasAndPtrType(t *types.Type) *types.Type {
 | 
				
			||||||
 | 
						var prev *types.Type
 | 
				
			||||||
 | 
						for prev != t {
 | 
				
			||||||
 | 
							prev = t
 | 
				
			||||||
 | 
							if t.Kind == types.Alias {
 | 
				
			||||||
 | 
								t = t.Underlying
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if t.Kind == types.Pointer {
 | 
				
			||||||
 | 
								t = t.Elem
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return t
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (g openAPITypeWriter) generateMapProperty(t *types.Type) error {
 | 
				
			||||||
 | 
						keyType := resolveAliasAndPtrType(t.Key)
 | 
				
			||||||
 | 
						elemType := resolveAliasAndPtrType(t.Elem)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// According to OpenAPI examples, only map from string is supported
 | 
				
			||||||
 | 
						if keyType.Name.Name != "string" {
 | 
				
			||||||
 | 
							return fmt.Errorf("map with non-string keys are not supported by OpenAPI in %v", t)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						g.Do("Type: []string{\"object\"},\n", nil)
 | 
				
			||||||
 | 
						g.Do("AdditionalProperties: &spec.SchemaOrBool{\nSchema: &spec.Schema{\nSchemaProps: spec.SchemaProps{\n", nil)
 | 
				
			||||||
 | 
						typeString, format := openapi.GetOpenAPITypeFormat(elemType.String())
 | 
				
			||||||
 | 
						if typeString != "" {
 | 
				
			||||||
 | 
							g.generateSimpleProperty(typeString, format)
 | 
				
			||||||
 | 
							g.Do("},\n},\n},\n", nil)
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						switch elemType.Kind {
 | 
				
			||||||
 | 
						case types.Builtin:
 | 
				
			||||||
 | 
							return fmt.Errorf("please add type %v to getOpenAPITypeFormat function", elemType)
 | 
				
			||||||
 | 
						case types.Struct:
 | 
				
			||||||
 | 
							g.generateReferenceProperty(elemType)
 | 
				
			||||||
 | 
						case types.Slice, types.Array:
 | 
				
			||||||
 | 
							g.generateSliceProperty(elemType)
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return fmt.Errorf("map Element kind %v is not supported in %v", elemType.Kind, t.Name)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						g.Do("},\n},\n},\n", nil)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (g openAPITypeWriter) generateSliceProperty(t *types.Type) error {
 | 
				
			||||||
 | 
						elemType := resolveAliasAndPtrType(t.Elem)
 | 
				
			||||||
 | 
						g.Do("Type: []string{\"array\"},\n", nil)
 | 
				
			||||||
 | 
						g.Do("Items: &spec.SchemaOrArray{\nSchema: &spec.Schema{\nSchemaProps: spec.SchemaProps{\n", nil)
 | 
				
			||||||
 | 
						typeString, format := openapi.GetOpenAPITypeFormat(elemType.String())
 | 
				
			||||||
 | 
						if typeString != "" {
 | 
				
			||||||
 | 
							g.generateSimpleProperty(typeString, format)
 | 
				
			||||||
 | 
							g.Do("},\n},\n},\n", nil)
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						switch elemType.Kind {
 | 
				
			||||||
 | 
						case types.Builtin:
 | 
				
			||||||
 | 
							return fmt.Errorf("please add type %v to getOpenAPITypeFormat function", elemType)
 | 
				
			||||||
 | 
						case types.Struct:
 | 
				
			||||||
 | 
							g.generateReferenceProperty(elemType)
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return fmt.Errorf("slice Element kind %v is not supported in %v", elemType.Kind, t)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						g.Do("},\n},\n},\n", nil)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										204
									
								
								vendor/k8s.io/kube-openapi/pkg/handler/handler.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								vendor/k8s.io/kube-openapi/pkg/handler/handler.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,204 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2017 The Kubernetes Authors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package handler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"compress/gzip"
 | 
				
			||||||
 | 
						"crypto/sha512"
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"gopkg.in/yaml.v2"
 | 
				
			||||||
 | 
						"mime"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
						"sync"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/NYTimes/gziphandler"
 | 
				
			||||||
 | 
						"github.com/emicklei/go-restful"
 | 
				
			||||||
 | 
						"github.com/go-openapi/spec"
 | 
				
			||||||
 | 
						"github.com/golang/protobuf/proto"
 | 
				
			||||||
 | 
						"github.com/googleapis/gnostic/OpenAPIv2"
 | 
				
			||||||
 | 
						"github.com/googleapis/gnostic/compiler"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"k8s.io/kube-openapi/pkg/builder"
 | 
				
			||||||
 | 
						"k8s.io/kube-openapi/pkg/common"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						jsonExt = ".json"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mimeJson = "application/json"
 | 
				
			||||||
 | 
						// TODO(mehdy): change @68f4ded to a version tag when gnostic add version tags.
 | 
				
			||||||
 | 
						mimePb   = "application/com.github.googleapis.gnostic.OpenAPIv2@68f4ded+protobuf"
 | 
				
			||||||
 | 
						mimePbGz = "application/x-gzip"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// OpenAPIService is the service responsible for serving OpenAPI spec. It has
 | 
				
			||||||
 | 
					// the ability to safely change the spec while serving it.
 | 
				
			||||||
 | 
					type OpenAPIService struct {
 | 
				
			||||||
 | 
						// rwMutex protects All members of this service.
 | 
				
			||||||
 | 
						rwMutex sync.RWMutex
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						orgSpec      *spec.Swagger
 | 
				
			||||||
 | 
						lastModified time.Time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						specBytes []byte
 | 
				
			||||||
 | 
						specPb    []byte
 | 
				
			||||||
 | 
						specPbGz  []byte
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						specBytesETag string
 | 
				
			||||||
 | 
						specPbETag    string
 | 
				
			||||||
 | 
						specPbGzETag  string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() {
 | 
				
			||||||
 | 
						mime.AddExtensionType(".json", mimeJson)
 | 
				
			||||||
 | 
						mime.AddExtensionType(".pb-v1", mimePb)
 | 
				
			||||||
 | 
						mime.AddExtensionType(".gz", mimePbGz)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func computeETag(data []byte) string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("\"%X\"", sha512.Sum512(data))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// BuildAndRegisterOpenAPIService builds the spec and registers a handler to provides access to it.
 | 
				
			||||||
 | 
					// Use this method if your OpenAPI spec is static. If you want to update the spec, use BuildOpenAPISpec then RegisterOpenAPIService.
 | 
				
			||||||
 | 
					func BuildAndRegisterOpenAPIService(servePath string, webServices []*restful.WebService, config *common.Config, handler common.PathHandler) (*OpenAPIService, error) {
 | 
				
			||||||
 | 
						spec, err := builder.BuildOpenAPISpec(webServices, config)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return RegisterOpenAPIService(spec, servePath, handler)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RegisterOpenAPIService registers a handler to provides access to provided swagger spec.
 | 
				
			||||||
 | 
					// Note: servePath should end with ".json" as the RegisterOpenAPIService assume it is serving a
 | 
				
			||||||
 | 
					// json file and will also serve .pb and .gz files.
 | 
				
			||||||
 | 
					func RegisterOpenAPIService(openapiSpec *spec.Swagger, servePath string, handler common.PathHandler) (*OpenAPIService, error) {
 | 
				
			||||||
 | 
						if !strings.HasSuffix(servePath, jsonExt) {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("serving path must end with \"%s\"", jsonExt)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						servePathBase := strings.TrimSuffix(servePath, jsonExt)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						o := OpenAPIService{}
 | 
				
			||||||
 | 
						if err := o.UpdateSpec(openapiSpec); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						type fileInfo struct {
 | 
				
			||||||
 | 
							ext            string
 | 
				
			||||||
 | 
							getDataAndETag func() ([]byte, string, time.Time)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						files := []fileInfo{
 | 
				
			||||||
 | 
							{".json", o.getSwaggerBytes},
 | 
				
			||||||
 | 
							{"-2.0.0.json", o.getSwaggerBytes},
 | 
				
			||||||
 | 
							{"-2.0.0.pb-v1", o.getSwaggerPbBytes},
 | 
				
			||||||
 | 
							{"-2.0.0.pb-v1.gz", o.getSwaggerPbGzBytes},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, file := range files {
 | 
				
			||||||
 | 
							path := servePathBase + file.ext
 | 
				
			||||||
 | 
							getDataAndETag := file.getDataAndETag
 | 
				
			||||||
 | 
							handler.Handle(path, gziphandler.GzipHandler(http.HandlerFunc(
 | 
				
			||||||
 | 
								func(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
									data, etag, lastModified := getDataAndETag()
 | 
				
			||||||
 | 
									w.Header().Set("Etag", etag)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// ServeContent will take care of caching using eTag.
 | 
				
			||||||
 | 
									http.ServeContent(w, r, path, lastModified, bytes.NewReader(data))
 | 
				
			||||||
 | 
								}),
 | 
				
			||||||
 | 
							))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &o, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (o *OpenAPIService) getSwaggerBytes() ([]byte, string, time.Time) {
 | 
				
			||||||
 | 
						o.rwMutex.RLock()
 | 
				
			||||||
 | 
						defer o.rwMutex.RUnlock()
 | 
				
			||||||
 | 
						return o.specBytes, o.specBytesETag, o.lastModified
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (o *OpenAPIService) getSwaggerPbBytes() ([]byte, string, time.Time) {
 | 
				
			||||||
 | 
						o.rwMutex.RLock()
 | 
				
			||||||
 | 
						defer o.rwMutex.RUnlock()
 | 
				
			||||||
 | 
						return o.specPb, o.specPbETag, o.lastModified
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (o *OpenAPIService) getSwaggerPbGzBytes() ([]byte, string, time.Time) {
 | 
				
			||||||
 | 
						o.rwMutex.RLock()
 | 
				
			||||||
 | 
						defer o.rwMutex.RUnlock()
 | 
				
			||||||
 | 
						return o.specPbGz, o.specPbGzETag, o.lastModified
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (o *OpenAPIService) UpdateSpec(openapiSpec *spec.Swagger) (err error) {
 | 
				
			||||||
 | 
						orgSpec := openapiSpec
 | 
				
			||||||
 | 
						specBytes, err := json.MarshalIndent(openapiSpec, " ", " ")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						specPb, err := toProtoBinary(specBytes)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						specPbGz := toGzip(specPb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						specBytesETag := computeETag(specBytes)
 | 
				
			||||||
 | 
						specPbETag := computeETag(specPb)
 | 
				
			||||||
 | 
						specPbGzETag := computeETag(specPbGz)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						lastModified := time.Now()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						o.rwMutex.Lock()
 | 
				
			||||||
 | 
						defer o.rwMutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						o.orgSpec = orgSpec
 | 
				
			||||||
 | 
						o.specBytes = specBytes
 | 
				
			||||||
 | 
						o.specPb = specPb
 | 
				
			||||||
 | 
						o.specPbGz = specPbGz
 | 
				
			||||||
 | 
						o.specBytesETag = specBytesETag
 | 
				
			||||||
 | 
						o.specPbETag = specPbETag
 | 
				
			||||||
 | 
						o.specPbGzETag = specPbGzETag
 | 
				
			||||||
 | 
						o.lastModified = lastModified
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func toProtoBinary(spec []byte) ([]byte, error) {
 | 
				
			||||||
 | 
						var info yaml.MapSlice
 | 
				
			||||||
 | 
						err := yaml.Unmarshal(spec, &info)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						document, err := openapi_v2.NewDocument(info, compiler.NewContext("$root", nil))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return proto.Marshal(document)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func toGzip(data []byte) []byte {
 | 
				
			||||||
 | 
						var buf bytes.Buffer
 | 
				
			||||||
 | 
						zw := gzip.NewWriter(&buf)
 | 
				
			||||||
 | 
						zw.Write(data)
 | 
				
			||||||
 | 
						zw.Close()
 | 
				
			||||||
 | 
						return buf.Bytes()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										79
									
								
								vendor/k8s.io/kube-openapi/pkg/util/trie.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								vendor/k8s.io/kube-openapi/pkg/util/trie.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2016 The Kubernetes Authors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package util
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A simple trie implementation with Add and HasPrefix methods only.
 | 
				
			||||||
 | 
					type Trie struct {
 | 
				
			||||||
 | 
						children map[byte]*Trie
 | 
				
			||||||
 | 
						wordTail bool
 | 
				
			||||||
 | 
						word     string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewTrie creates a Trie and add all strings in the provided list to it.
 | 
				
			||||||
 | 
					func NewTrie(list []string) Trie {
 | 
				
			||||||
 | 
						ret := Trie{
 | 
				
			||||||
 | 
							children: make(map[byte]*Trie),
 | 
				
			||||||
 | 
							wordTail: false,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, v := range list {
 | 
				
			||||||
 | 
							ret.Add(v)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ret
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Add adds a word to this trie
 | 
				
			||||||
 | 
					func (t *Trie) Add(v string) {
 | 
				
			||||||
 | 
						root := t
 | 
				
			||||||
 | 
						for _, b := range []byte(v) {
 | 
				
			||||||
 | 
							child, exists := root.children[b]
 | 
				
			||||||
 | 
							if !exists {
 | 
				
			||||||
 | 
								child = &Trie{
 | 
				
			||||||
 | 
									children: make(map[byte]*Trie),
 | 
				
			||||||
 | 
									wordTail: false,
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								root.children[b] = child
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							root = child
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						root.wordTail = true
 | 
				
			||||||
 | 
						root.word = v
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// HasPrefix returns true of v has any of the prefixes stored in this trie.
 | 
				
			||||||
 | 
					func (t *Trie) HasPrefix(v string) bool {
 | 
				
			||||||
 | 
						_, has := t.GetPrefix(v)
 | 
				
			||||||
 | 
						return has
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetPrefix is like HasPrefix but return the prefix in case of match or empty string otherwise.
 | 
				
			||||||
 | 
					func (t *Trie) GetPrefix(v string) (string, bool) {
 | 
				
			||||||
 | 
						root := t
 | 
				
			||||||
 | 
						if root.wordTail {
 | 
				
			||||||
 | 
							return root.word, true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, b := range []byte(v) {
 | 
				
			||||||
 | 
							child, exists := root.children[b]
 | 
				
			||||||
 | 
							if !exists {
 | 
				
			||||||
 | 
								return "", false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if child.wordTail {
 | 
				
			||||||
 | 
								return child.word, true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							root = child
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return "", false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user