apiextensions: merge openapi spec ignore path conflict

This commit is contained in:
Haowei Cai 2019-08-28 13:33:49 -07:00
parent b2c9b1f729
commit 81e00f0b7b
2 changed files with 19 additions and 6 deletions

View File

@ -18,12 +18,13 @@ package builder
import (
"github.com/go-openapi/spec"
"k8s.io/kube-openapi/pkg/aggregator"
)
// MergeSpecs aggregates all OpenAPI specs, reusing the metadata of the first, static spec as the basis.
// Later paths and definitions override earlier ones. None of the input is mutated, but input
// and output share data structures.
func MergeSpecs(staticSpec *spec.Swagger, crdSpecs ...*spec.Swagger) *spec.Swagger {
// The static spec has the highest priority, and its paths and definitions won't get overlapped by
// user-defined CRDs. None of the input is mutated, but input and output share data structures.
func MergeSpecs(staticSpec *spec.Swagger, crdSpecs ...*spec.Swagger) (*spec.Swagger, error) {
// create shallow copy of staticSpec, but replace paths and definitions because we modify them.
specToReturn := *staticSpec
if staticSpec.Definitions != nil {
@ -41,11 +42,19 @@ func MergeSpecs(staticSpec *spec.Swagger, crdSpecs ...*spec.Swagger) *spec.Swagg
}
}
crdSpec := &spec.Swagger{}
for _, s := range crdSpecs {
mergeSpec(&specToReturn, s)
// merge specs without checking conflicts, since the naming controller prevents
// conflicts between user-defined CRDs
mergeSpec(crdSpec, s)
}
return &specToReturn
// The static spec has the highest priority. Resolve conflicts to prevent user-defined
// CRDs potentially overlapping the built-in apiextensions API
if err := aggregator.MergeSpecsIgnorePathConflict(&specToReturn, crdSpec); err != nil {
return nil, err
}
return &specToReturn, nil
}
// mergeSpec copies paths and definitions from source to dest, mutating dest, but not source.

View File

@ -218,7 +218,11 @@ func (c *Controller) updateSpecLocked() error {
crdSpecs = append(crdSpecs, s)
}
}
return c.openAPIService.UpdateSpec(builder.MergeSpecs(c.staticSpec, crdSpecs...))
mergedSpec, err := builder.MergeSpecs(c.staticSpec, crdSpecs...)
if err != nil {
return fmt.Errorf("failed to merge specs: %v", err)
}
return c.openAPIService.UpdateSpec(mergedSpec)
}
func (c *Controller) addCustomResourceDefinition(obj interface{}) {