...
1
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 defer 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
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.GenericConfig.OpenAPIConfig = framework.DefaultOpenAPIConfig()
81 config.GenericConfig.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 }
122
View as plain text