Skip to content

Commit 8be5b05

Browse files
luksastaebler
authored andcommitted
Serve OpenAPI spec only when --serve-openapi-spec switch is enabled (openshift#1612)
* support serving openapi spec * Add runtime option to toggle if the API server exposes the OpenAPI spec
1 parent 19fb30e commit 8be5b05

File tree

7 files changed

+187
-5
lines changed

7 files changed

+187
-5
lines changed

Diff for: Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ $(BINDIR)/e2e.test: .init $(NEWEST_E2ETEST_SOURCE) $(NEWEST_GO_FILE)
191191
$(DOCKER_CMD) $(BINDIR)/openapi-gen \
192192
--v 1 --logtostderr \
193193
--go-header-file "vendor/github.com/kubernetes/repo-infra/verify/boilerplate/boilerplate.go.txt" \
194-
--input-dirs "github.com/kubernetes-incubator/service-catalog/pkg/apis/servicecatalog/v1beta1,k8s.io/api/core/v1,k8s.io/apimachinery/pkg/apis/meta/v1" \
194+
--input-dirs "github.com/kubernetes-incubator/service-catalog/pkg/apis/servicecatalog/v1beta1,k8s.io/api/core/v1,k8s.io/apimachinery/pkg/apis/meta/v1,k8s.io/apimachinery/pkg/version,k8s.io/apimachinery/pkg/runtime" \
195195
--output-package "github.com/kubernetes-incubator/service-catalog/pkg/openapi"
196196
touch $@
197197

Diff for: charts/catalog/templates/apiserver-deployment.yaml

+5-2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ spec:
6161
- --feature-gates
6262
- OriginatingIdentity=true
6363
{{- end }}
64+
{{- if .Values.apiserver.serveOpenAPISpec }}
65+
- --serve-openapi-spec
66+
{{- end }}
6467
ports:
6568
- containerPort: 8443
6669
volumeMounts:
@@ -94,10 +97,10 @@ spec:
9497
resources:
9598
requests:
9699
cpu: 100m
97-
memory: 20Mi
100+
memory: 30Mi
98101
limits:
99102
cpu: 100m
100-
memory: 30Mi
103+
memory: 40Mi
101104
env:
102105
- name: ETCD_DATA_DIR
103106
value: /etcd-data-dir

Diff for: charts/catalog/values.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ apiserver:
6767
# If specified, audit log goes to specified path.
6868
logPath: "/tmp/service-catalog-apiserver-audit.log"
6969
serviceAccount: service-catalog-apiserver
70+
# if true, makes the API server serve the OpenAPI schema (which is problematic with older versions of kubectl)
71+
serveOpenAPISpec: false
7072
controllerManager:
7173
# Log level; valid values are in the range 0 - 10
7274
verbosity: 10

Diff for: cmd/apiserver/app/server/options.go

+9
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ type ServiceCatalogServerOptions struct {
5757
DisableAuth bool
5858
// StandaloneMode if true asserts that we will not depend on a kube-apiserver
5959
StandaloneMode bool
60+
// whether or not to serve the OpenAPI spec (at /swagger.json)
61+
ServeOpenAPISpec bool
6062
}
6163

6264
// NewServiceCatalogServerOptions creates a new instances of
@@ -95,6 +97,13 @@ func (s *ServiceCatalogServerOptions) AddFlags(flags *pflag.FlagSet) {
9597
"Disable authentication and authorization for testing purposes",
9698
)
9799

100+
flags.BoolVar(
101+
&s.ServeOpenAPISpec,
102+
"serve-openapi-spec",
103+
false,
104+
"Whether this API server should serve the OpenAPI spec (problematic with older versions of kubectl)",
105+
)
106+
98107
s.GenericServerRunOptions.AddUniversalFlags(flags)
99108
s.AdmissionOptions.AddFlags(flags)
100109
s.SecureServingOptions.AddFlags(flags)

Diff for: cmd/apiserver/app/server/util.go

+20-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ package server
1919
import (
2020
"fmt"
2121
"net"
22+
"strings"
2223
"time"
2324

25+
"github.com/go-openapi/spec"
2426
"github.com/golang/glog"
2527

2628
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -36,6 +38,7 @@ import (
3638
"github.com/kubernetes-incubator/service-catalog/pkg/apiserver/authenticator"
3739
"github.com/kubernetes-incubator/service-catalog/pkg/client/clientset_generated/internalclientset"
3840
informers "github.com/kubernetes-incubator/service-catalog/pkg/client/informers_generated/internalversion"
41+
"github.com/kubernetes-incubator/service-catalog/pkg/openapi"
3942
"github.com/kubernetes-incubator/service-catalog/pkg/version"
4043
)
4144

@@ -87,8 +90,23 @@ func buildGenericConfig(s *ServiceCatalogServerOptions) (*genericapiserver.Recom
8790
return nil, nil, err
8891
}
8992

90-
// TODO: add support for OpenAPI config
91-
// see https://github.com/kubernetes-incubator/service-catalog/issues/721
93+
if s.ServeOpenAPISpec {
94+
genericConfig.OpenAPIConfig = genericapiserver.DefaultOpenAPIConfig(
95+
openapi.GetOpenAPIDefinitions, api.Scheme)
96+
if genericConfig.OpenAPIConfig.Info == nil {
97+
genericConfig.OpenAPIConfig.Info = &spec.Info{}
98+
}
99+
if genericConfig.OpenAPIConfig.Info.Version == "" {
100+
if genericConfig.Version != nil {
101+
genericConfig.OpenAPIConfig.Info.Version = strings.Split(genericConfig.Version.String(), "-")[0]
102+
} else {
103+
genericConfig.OpenAPIConfig.Info.Version = "unversioned"
104+
}
105+
}
106+
} else {
107+
glog.Warning("OpenAPI spec will not be served")
108+
}
109+
92110
genericConfig.SwaggerConfig = genericapiserver.DefaultSwaggerConfig()
93111
// TODO: investigate if we need metrics unique to service catalog, but take defaults for now
94112
// see https://github.com/kubernetes-incubator/service-catalog/issues/677

Diff for: pkg/openapi/openapi_generated.go

+149
Original file line numberDiff line numberDiff line change
@@ -11049,5 +11049,154 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
1104911049
Dependencies: []string{
1105011050
"k8s.io/apimachinery/pkg/runtime.RawExtension"},
1105111051
},
11052+
"k8s.io/apimachinery/pkg/runtime.RawExtension": {
11053+
Schema: spec.Schema{
11054+
SchemaProps: spec.SchemaProps{
11055+
Description: "RawExtension is used to hold extensions in external versions.\n\nTo use this, make a field which has RawExtension as its type in your external, versioned struct, and Object in your internal struct. You also need to register your various plugin types.\n\n// Internal package: type MyAPIObject struct {\n\truntime.TypeMeta `json:\",inline\"`\n\tMyPlugin runtime.Object `json:\"myPlugin\"`\n} type PluginA struct {\n\tAOption string `json:\"aOption\"`\n}\n\n// External package: type MyAPIObject struct {\n\truntime.TypeMeta `json:\",inline\"`\n\tMyPlugin runtime.RawExtension `json:\"myPlugin\"`\n} type PluginA struct {\n\tAOption string `json:\"aOption\"`\n}\n\n// On the wire, the JSON will look something like this: {\n\t\"kind\":\"MyAPIObject\",\n\t\"apiVersion\":\"v1\",\n\t\"myPlugin\": {\n\t\t\"kind\":\"PluginA\",\n\t\t\"aOption\":\"foo\",\n\t},\n}\n\nSo what happens? Decode first uses json or yaml to unmarshal the serialized data into your external MyAPIObject. That causes the raw JSON to be stored, but not unpacked. The next step is to copy (using pkg/conversion) into the internal struct. The runtime package's DefaultScheme has conversion functions installed which will unpack the JSON stored in RawExtension, turning it into the correct object type, and storing it in the Object. (TODO: In the case where the object is of an unknown type, a runtime.Unknown object will be created and stored.)",
11056+
Properties: map[string]spec.Schema{
11057+
"Raw": {
11058+
SchemaProps: spec.SchemaProps{
11059+
Description: "Raw is the underlying serialization of this object.",
11060+
Type: []string{"string"},
11061+
Format: "byte",
11062+
},
11063+
},
11064+
},
11065+
Required: []string{"Raw"},
11066+
},
11067+
},
11068+
Dependencies: []string{},
11069+
},
11070+
"k8s.io/apimachinery/pkg/runtime.TypeMeta": {
11071+
Schema: spec.Schema{
11072+
SchemaProps: spec.SchemaProps{
11073+
Description: "TypeMeta is shared by all top level objects. The proper way to use it is to inline it in your type, like this: type MyAwesomeAPIObject struct {\n runtime.TypeMeta `json:\",inline\"`\n ... // other fields\n} func (obj *MyAwesomeAPIObject) SetGroupVersionKind(gvk *metav1.GroupVersionKind) { metav1.UpdateTypeMeta(obj,gvk) }; GroupVersionKind() *GroupVersionKind\n\nTypeMeta is provided here for convenience. You may use it directly from this package or define your own with the same fields.",
11074+
Properties: map[string]spec.Schema{
11075+
"apiVersion": {
11076+
SchemaProps: spec.SchemaProps{
11077+
Type: []string{"string"},
11078+
Format: "",
11079+
},
11080+
},
11081+
"kind": {
11082+
SchemaProps: spec.SchemaProps{
11083+
Type: []string{"string"},
11084+
Format: "",
11085+
},
11086+
},
11087+
},
11088+
},
11089+
},
11090+
Dependencies: []string{},
11091+
},
11092+
"k8s.io/apimachinery/pkg/runtime.Unknown": {
11093+
Schema: spec.Schema{
11094+
SchemaProps: spec.SchemaProps{
11095+
Description: "Unknown allows api objects with unknown types to be passed-through. This can be used to deal with the API objects from a plug-in. Unknown objects still have functioning TypeMeta features-- kind, version, etc. metadata and field mutatation.",
11096+
Properties: map[string]spec.Schema{
11097+
"apiVersion": {
11098+
SchemaProps: spec.SchemaProps{
11099+
Type: []string{"string"},
11100+
Format: "",
11101+
},
11102+
},
11103+
"kind": {
11104+
SchemaProps: spec.SchemaProps{
11105+
Type: []string{"string"},
11106+
Format: "",
11107+
},
11108+
},
11109+
"Raw": {
11110+
SchemaProps: spec.SchemaProps{
11111+
Description: "Raw will hold the complete serialized object which couldn't be matched with a registered type. Most likely, nothing should be done with this except for passing it through the system.",
11112+
Type: []string{"string"},
11113+
Format: "byte",
11114+
},
11115+
},
11116+
"ContentEncoding": {
11117+
SchemaProps: spec.SchemaProps{
11118+
Description: "ContentEncoding is encoding used to encode 'Raw' data. Unspecified means no encoding.",
11119+
Type: []string{"string"},
11120+
Format: "",
11121+
},
11122+
},
11123+
"ContentType": {
11124+
SchemaProps: spec.SchemaProps{
11125+
Description: "ContentType is serialization method used to serialize 'Raw'. Unspecified means ContentTypeJSON.",
11126+
Type: []string{"string"},
11127+
Format: "",
11128+
},
11129+
},
11130+
},
11131+
Required: []string{"Raw", "ContentEncoding", "ContentType"},
11132+
},
11133+
},
11134+
Dependencies: []string{},
11135+
},
11136+
"k8s.io/apimachinery/pkg/version.Info": {
11137+
Schema: spec.Schema{
11138+
SchemaProps: spec.SchemaProps{
11139+
Description: "Info contains versioning information. how we'll want to distribute that information.",
11140+
Properties: map[string]spec.Schema{
11141+
"major": {
11142+
SchemaProps: spec.SchemaProps{
11143+
Type: []string{"string"},
11144+
Format: "",
11145+
},
11146+
},
11147+
"minor": {
11148+
SchemaProps: spec.SchemaProps{
11149+
Type: []string{"string"},
11150+
Format: "",
11151+
},
11152+
},
11153+
"gitVersion": {
11154+
SchemaProps: spec.SchemaProps{
11155+
Type: []string{"string"},
11156+
Format: "",
11157+
},
11158+
},
11159+
"gitCommit": {
11160+
SchemaProps: spec.SchemaProps{
11161+
Type: []string{"string"},
11162+
Format: "",
11163+
},
11164+
},
11165+
"gitTreeState": {
11166+
SchemaProps: spec.SchemaProps{
11167+
Type: []string{"string"},
11168+
Format: "",
11169+
},
11170+
},
11171+
"buildDate": {
11172+
SchemaProps: spec.SchemaProps{
11173+
Type: []string{"string"},
11174+
Format: "",
11175+
},
11176+
},
11177+
"goVersion": {
11178+
SchemaProps: spec.SchemaProps{
11179+
Type: []string{"string"},
11180+
Format: "",
11181+
},
11182+
},
11183+
"compiler": {
11184+
SchemaProps: spec.SchemaProps{
11185+
Type: []string{"string"},
11186+
Format: "",
11187+
},
11188+
},
11189+
"platform": {
11190+
SchemaProps: spec.SchemaProps{
11191+
Type: []string{"string"},
11192+
Format: "",
11193+
},
11194+
},
11195+
},
11196+
Required: []string{"major", "minor", "gitVersion", "gitCommit", "gitTreeState", "buildDate", "goVersion", "compiler", "platform"},
11197+
},
11198+
},
11199+
Dependencies: []string{},
11200+
},
1105211201
}
1105311202
}

Diff for: test/integration/framework.go

+1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ func withConfigGetFreshApiserverAndClient(
102102
AuditOptions: genericserveroptions.NewAuditOptions(),
103103
DisableAuth: true,
104104
StandaloneMode: true, // this must be true because we have no kube server for integration.
105+
ServeOpenAPISpec: true,
105106
}
106107
options.SecureServingOptions.BindPort = securePort
107108
options.SecureServingOptions.ServerCert.CertDirectory = certDir

0 commit comments

Comments
 (0)