Skip to content

Commit b0158ce

Browse files
authored
Merge pull request kubernetes#75399 from sttts/sttts-initial-bulk-openapi-merge
apiextensions: merge OpenAPI specs once after cache sync
2 parents 753a6ed + a7f9ffd commit b0158ce

File tree

2 files changed

+42
-5
lines changed

2 files changed

+42
-5
lines changed

staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ go_library(
2121
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
2222
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
2323
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
24+
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
2425
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
2526
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
2627
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",

staging/src/k8s.io/apiextensions-apiserver/pkg/controller/openapi/controller.go

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424

2525
"github.com/go-openapi/spec"
2626
"k8s.io/apimachinery/pkg/api/errors"
27+
"k8s.io/apimachinery/pkg/labels"
2728
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
2829
"k8s.io/apimachinery/pkg/util/wait"
2930
"k8s.io/client-go/tools/cache"
@@ -89,6 +90,29 @@ func (c *Controller) Run(staticSpec *spec.Swagger, openAPIService *handler.OpenA
8990
return
9091
}
9192

93+
// create initial spec to avoid merging once per CRD on startup
94+
crds, err := c.crdLister.List(labels.Everything())
95+
if err != nil {
96+
utilruntime.HandleError(fmt.Errorf("failed to initially list all CRDs: %v", err))
97+
return
98+
}
99+
for _, crd := range crds {
100+
if !apiextensions.IsCRDConditionTrue(crd, apiextensions.Established) {
101+
continue
102+
}
103+
newSpecs, changed, err := buildVersionSpecs(crd, nil)
104+
if err != nil {
105+
utilruntime.HandleError(fmt.Errorf("failed to build OpenAPI spec of CRD %s: %v", crd.Name, err))
106+
} else if !changed {
107+
continue
108+
}
109+
c.crdSpecs[crd.Name] = newSpecs
110+
}
111+
if err := c.updateSpecLocked(); err != nil {
112+
utilruntime.HandleError(fmt.Errorf("failed to initially create OpenAPI spec for CRDs: %v", err))
113+
return
114+
}
115+
92116
// only start one worker thread since its a slow moving API
93117
go wait.Until(c.runWorker, time.Second, stopCh)
94118

@@ -147,6 +171,20 @@ func (c *Controller) sync(name string) error {
147171

148172
// compute CRD spec and see whether it changed
149173
oldSpecs := c.crdSpecs[crd.Name]
174+
newSpecs, changed, err := buildVersionSpecs(crd, oldSpecs)
175+
if err != nil {
176+
return err
177+
}
178+
if !changed {
179+
return nil
180+
}
181+
182+
// update specs of this CRD
183+
c.crdSpecs[crd.Name] = newSpecs
184+
return c.updateSpecLocked()
185+
}
186+
187+
func buildVersionSpecs(crd *apiextensions.CustomResourceDefinition, oldSpecs map[string]*spec.Swagger) (map[string]*spec.Swagger, bool, error) {
150188
newSpecs := map[string]*spec.Swagger{}
151189
anyChanged := false
152190
for _, v := range crd.Spec.Versions {
@@ -155,20 +193,18 @@ func (c *Controller) sync(name string) error {
155193
}
156194
spec, err := BuildSwagger(crd, v.Name)
157195
if err != nil {
158-
return err
196+
return nil, false, err
159197
}
160198
newSpecs[v.Name] = spec
161199
if oldSpecs[v.Name] == nil || !reflect.DeepEqual(oldSpecs[v.Name], spec) {
162200
anyChanged = true
163201
}
164202
}
165203
if !anyChanged && len(oldSpecs) == len(newSpecs) {
166-
return nil
204+
return newSpecs, false, nil
167205
}
168206

169-
// update specs of this CRD
170-
c.crdSpecs[crd.Name] = newSpecs
171-
return c.updateSpecLocked()
207+
return newSpecs, true, nil
172208
}
173209

174210
// updateSpecLocked aggregates all OpenAPI specs and updates openAPIService.

0 commit comments

Comments
 (0)