cli-runtime: make VerifiableQueryParam shared-parameter aware

This commit is contained in:
Dr. Stefan Schimanski 2023-07-17 08:57:00 +02:00
parent a4a607198a
commit e7be841957
No known key found for this signature in database
GPG Key ID: 4C68E0F19F95EC33
4 changed files with 70223 additions and 14 deletions

View File

@ -22,6 +22,7 @@ import (
openapi_v2 "github.com/google/gnostic-models/openapiv2"
yaml "gopkg.in/yaml.v2"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/discovery"
"k8s.io/client-go/dynamic"
@ -146,6 +147,11 @@ func hasGVKExtension(extensions []*openapi_v2.NamedAny, gvk schema.GroupVersionK
// specific group-version-kind supports the specific query parameter for
// the PATCH end-point.
func supportsQueryParam(doc *openapi_v2.Document, gvk schema.GroupVersionKind, queryParam VerifiableQueryParam) (bool, error) {
globalParams := map[string]*openapi_v2.NamedParameter{}
for _, p := range doc.GetParameters().GetAdditionalProperties() {
globalParams["#/parameters/"+p.GetName()] = p
}
for _, path := range doc.GetPaths().GetPath() {
// Is this describing the gvk we're looking for?
if !hasGVKExtension(path.GetValue().GetPatch().GetVendorExtension(), gvk) {
@ -155,6 +161,13 @@ func supportsQueryParam(doc *openapi_v2.Document, gvk schema.GroupVersionKind, q
if param.GetParameter().GetNonBodyParameter().GetQueryParameterSubSchema().GetName() == string(queryParam) {
return true, nil
}
// lookup global parameters
if ref := param.GetJsonReference().GetXRef(); ref != "" {
if globalParam, ok := globalParams[ref]; ok && globalParam != nil && globalParam.GetValue().GetNonBodyParameter().GetQueryParameterSubSchema().GetName() == string(queryParam) {
return true, nil
}
}
}
return false, nil
}

View File

@ -21,14 +21,20 @@ import (
"testing"
openapi_v2 "github.com/google/gnostic-models/openapiv2"
"k8s.io/apimachinery/pkg/runtime/schema"
openapitesting "k8s.io/kube-openapi/pkg/util/proto/testing"
)
var fakeSchema = openapitesting.Fake{Path: filepath.Join("..", "..", "artifacts", "openapi", "swagger.json")}
var fakeSchemaSharedParams = openapitesting.Fake{Path: filepath.Join("..", "..", "artifacts", "openapi", "swagger-with-shared-parameters.json")}
func TestSupportsQueryParam(t *testing.T) {
doc, err := fakeSchema.OpenAPISchema()
docInlineParams, err := fakeSchema.OpenAPISchema()
if err != nil {
t.Fatalf("Failed to get OpenAPI Schema: %v", err)
}
docSharedParams, err := fakeSchemaSharedParams.OpenAPISchema()
if err != nil {
t.Fatalf("Failed to get OpenAPI Schema: %v", err)
}
@ -81,19 +87,26 @@ func TestSupportsQueryParam(t *testing.T) {
},
}
for _, test := range tests {
supports, err := supportsQueryParam(doc, test.gvk, test.queryParam)
if supports != test.supports || ((err == nil) != test.success) {
errStr := "nil"
if test.success == false {
errStr = "err"
for name, doc := range map[string]*openapi_v2.Document{
"inline parameters": docInlineParams,
"shared parameters": docSharedParams,
} {
t.Run(name, func(t *testing.T) {
for _, test := range tests {
supports, err := supportsQueryParam(doc, test.gvk, test.queryParam)
if supports != test.supports || ((err == nil) != test.success) {
errStr := "nil"
if test.success == false {
errStr = "err"
}
t.Errorf("SupportsQueryParam(doc, %v, %v) = (%v, %v), expected (%v, %v)",
test.gvk, test.queryParam,
supports, err,
test.supports, errStr,
)
}
}
t.Errorf("SupportsQueryParam(doc, %v, %v) = (%v, %v), expected (%v, %v)",
test.gvk, test.queryParam,
supports, err,
test.supports, errStr,
)
}
})
}
}

View File

@ -18,6 +18,7 @@ package resource
import (
"fmt"
"strings"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic"
@ -124,9 +125,19 @@ func supportsQueryParamV3(doc *spec3.OpenAPI, gvk schema.GroupVersionKind, query
// Now look for the query parameter among the parameters
// for the PATCH operation.
for _, param := range op.OperationProps.Parameters {
if param.ParameterProps.Name == string(queryParam) {
if param.ParameterProps.Name == string(queryParam) && param.In == "query" {
return nil
}
// lookup global parameters
if ref := param.Refable.Ref.Ref.String(); strings.HasPrefix(ref, "#/parameters/") && doc.Components != nil {
k := strings.TrimPrefix(ref, "#/parameters/")
if globalParam, ok := doc.Components.Parameters[k]; ok && globalParam != nil {
if globalParam.In == "query" && globalParam.Name == string(queryParam) {
return nil
}
}
}
}
return NewParamUnsupportedError(gvk, queryParam)
}