Merge pull request #38219 from mbohlool/openapi_fix

Automatic merge from submit-queue

Fix pods/log OpenAPI/Swagger spec to return string instead of v1.Pod

log operation is part of pod and had the assumption of returning a v1.Pod. First I added the support for an operation to be able to customize its return object then add the support to pods/log operation to return an string as an object sample.

Fixes #37881
Cc @kubernetes/sig-api-machinery
This commit is contained in:
Kubernetes Submit Queue 2016-12-06 19:50:47 -08:00 committed by GitHub
commit 470222e0bb
7 changed files with 27 additions and 6 deletions

View File

@ -3638,7 +3638,7 @@
"200": { "200": {
"description": "OK", "description": "OK",
"schema": { "schema": {
"$ref": "#/definitions/v1.Pod" "type": "string"
} }
}, },
"401": { "401": {

View File

@ -8980,7 +8980,7 @@
"description": "API at /api/v1", "description": "API at /api/v1",
"operations": [ "operations": [
{ {
"type": "v1.Pod", "type": "string",
"method": "GET", "method": "GET",
"summary": "read log of the specified Pod", "summary": "read log of the specified Pod",
"nickname": "readNamespacedPodLog", "nickname": "readNamespacedPodLog",
@ -9070,7 +9070,7 @@
{ {
"code": 200, "code": 200,
"message": "OK", "message": "OK",
"responseModel": "v1.Pod" "responseModel": "string"
} }
], ],
"produces": [ "produces": [

View File

@ -8971,7 +8971,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<tr> <tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">200</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">success</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../definitions#_v1_pod">v1.Pod</a></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@ -33308,7 +33308,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
</div> </div>
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Last updated 2016-12-05 07:38:49 UTC Last updated 2016-12-06 22:35:20 UTC
</div> </div>
</div> </div>
</body> </body>

View File

@ -290,6 +290,10 @@ type StorageMetadata interface {
// ProducesMIMETypes returns a list of the MIME types the specified HTTP verb (GET, POST, DELETE, // ProducesMIMETypes returns a list of the MIME types the specified HTTP verb (GET, POST, DELETE,
// PATCH) can respond with. // PATCH) can respond with.
ProducesMIMETypes(verb string) []string ProducesMIMETypes(verb string) []string
// ProducesObject returns an object the specified HTTP verb respond with. It will overwrite storage object if
// it is not nil. Only the type of the return object matters, the value will be ignored.
ProducesObject(verb string) interface{}
} }
// ConnectRequest is an object passed to admission control for Connect operations // ConnectRequest is an object passed to admission control for Connect operations

View File

@ -213,7 +213,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
if err != nil { if err != nil {
return nil, err return nil, err
} }
versionedObject := indirectArbitraryPointer(versionedPtr) defaultVersionedObject := indirectArbitraryPointer(versionedPtr)
kind := fqKindToRegister.Kind kind := fqKindToRegister.Kind
hasSubresource := len(subresource) > 0 hasSubresource := len(subresource) > 0
@ -520,6 +520,10 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
Kind: fqKindToRegister, Kind: fqKindToRegister,
} }
for _, action := range actions { for _, action := range actions {
versionedObject := storageMeta.ProducesObject(action.Verb)
if versionedObject == nil {
versionedObject = defaultVersionedObject
}
reqScope.Namer = action.Namer reqScope.Namer = action.Namer
namespaced := "" namespaced := ""
if apiResource.Namespaced { if apiResource.Namespaced {
@ -1054,6 +1058,10 @@ func (defaultStorageMetadata) ProducesMIMETypes(verb string) []string {
return nil return nil
} }
func (defaultStorageMetadata) ProducesObject(verb string) interface{} {
return nil
}
// splitSubresource checks if the given storage path is the path of a subresource and returns // splitSubresource checks if the given storage path is the path of a subresource and returns
// the resource and subresource components. // the resource and subresource components.
func splitSubresource(path string) (string, string, error) { func splitSubresource(path string) (string, string, error) {

View File

@ -620,6 +620,10 @@ func (m *MetadataRESTStorage) ProducesMIMETypes(method string) []string {
return m.types return m.types
} }
func (m *MetadataRESTStorage) ProducesObject(verb string) interface{} {
return nil
}
var _ rest.StorageMetadata = &MetadataRESTStorage{} var _ rest.StorageMetadata = &MetadataRESTStorage{}
type GetWithOptionsRESTStorage struct { type GetWithOptionsRESTStorage struct {

View File

@ -55,6 +55,11 @@ func (r *LogREST) ProducesMIMETypes(verb string) []string {
} }
} }
// LogREST implements StorageMetadata, return string as the generating object
func (r *LogREST) ProducesObject(verb string) interface{} {
return ""
}
// Get retrieves a runtime.Object that will stream the contents of the pod log // Get retrieves a runtime.Object that will stream the contents of the pod log
func (r *LogREST) Get(ctx api.Context, name string, opts runtime.Object) (runtime.Object, error) { func (r *LogREST) Get(ctx api.Context, name string, opts runtime.Object) (runtime.Object, error) {
logOpts, ok := opts.(*api.PodLogOptions) logOpts, ok := opts.(*api.PodLogOptions)