k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/test/integration/apiserver/openapi/openapi_enum_test.go (about) 1 /* 2 Copyright 2021 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package openapi 18 19 import ( 20 "encoding/json" 21 "net/http" 22 "testing" 23 24 "k8s.io/apiserver/pkg/features" 25 utilfeature "k8s.io/apiserver/pkg/util/feature" 26 "k8s.io/apiserver/pkg/util/openapi" 27 restclient "k8s.io/client-go/rest" 28 featuregatetesting "k8s.io/component-base/featuregate/testing" 29 "k8s.io/kube-openapi/pkg/common" 30 "k8s.io/kube-openapi/pkg/validation/spec" 31 "k8s.io/kubernetes/pkg/controlplane" 32 generated "k8s.io/kubernetes/pkg/generated/openapi" 33 "k8s.io/kubernetes/test/integration/framework" 34 "k8s.io/kubernetes/test/utils/ktesting" 35 ) 36 37 func TestEnablingOpenAPIEnumTypes(t *testing.T) { 38 const typeToAddEnum = "k8s.io/api/core/v1.ContainerPort" 39 const typeToCheckEnum = "io.k8s.api.core.v1.ContainerPort" 40 41 for _, tc := range []struct { 42 name string 43 featureEnabled bool 44 enumShouldExist bool 45 }{ 46 { 47 name: "disabled", 48 featureEnabled: false, 49 enumShouldExist: false, 50 }, 51 { 52 name: "enabled", 53 featureEnabled: true, 54 enumShouldExist: true, 55 }, 56 } { 57 t.Run(tc.name, func(t *testing.T) { 58 tCtx := ktesting.Init(t) 59 featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.OpenAPIEnums, tc.featureEnabled) 60 61 getDefinitionsFn := openapi.GetOpenAPIDefinitionsWithoutDisabledFeatures(func(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { 62 defs := generated.GetOpenAPIDefinitions(ref) 63 def := defs[typeToAddEnum] 64 // replace protocol to add the would-be enum field. 65 def.Schema.Properties["protocol"] = spec.Schema{ 66 SchemaProps: spec.SchemaProps{ 67 Description: "Protocol for port. Must be UDP, TCP, or SCTP. Defaults to \\\"TCP\\\".\\n\\nPossible enum values:\\n - `SCTP`: is the SCTP protocol.\\n - `TCP`: is the TCP protocol.\\n - `UDP`: is the UDP protocol.", 68 Default: "TCP", 69 Type: []string{"string"}, 70 Format: "", 71 Enum: []interface{}{"SCTP", "TCP", "UDP"}, 72 }, 73 } 74 defs[typeToAddEnum] = def 75 return defs 76 }) 77 78 _, kubeConfig, tearDownFn := framework.StartTestServer(tCtx, t, framework.TestServerSetup{ 79 ModifyServerConfig: func(config *controlplane.Config) { 80 config.ControlPlane.Generic.OpenAPIConfig = framework.DefaultOpenAPIConfig() 81 config.ControlPlane.Generic.OpenAPIConfig.GetDefinitions = getDefinitionsFn 82 }, 83 }) 84 defer tearDownFn() 85 86 rt, err := restclient.TransportFor(kubeConfig) 87 if err != nil { 88 t.Fatal(err) 89 } 90 91 req, err := http.NewRequest("GET", kubeConfig.Host+"/openapi/v2", nil) 92 if err != nil { 93 t.Fatal(err) 94 } 95 resp, err := rt.RoundTrip(req) 96 if err != nil { 97 t.Fatal(err) 98 } 99 var body struct { 100 Definitions map[string]struct { 101 Properties map[string]struct { 102 Description string `json:"description"` 103 Type string `json:"type"` 104 Enum []string `json:"enum"` 105 } `json:"properties"` 106 } `json:"definitions"` 107 } 108 err = json.NewDecoder(resp.Body).Decode(&body) 109 if err != nil { 110 t.Fatal(err) 111 } 112 protocol, ok := body.Definitions[typeToCheckEnum].Properties["protocol"] 113 if !ok { 114 t.Fatalf("protocol not found in properties in %v", body) 115 } 116 if enumExists := len(protocol.Enum) > 0; enumExists != tc.enumShouldExist { 117 t.Errorf("expect enum exists: %v, but got %v", tc.enumShouldExist, enumExists) 118 } 119 }) 120 } 121 }