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 ( import (
"github.com/go-openapi/spec" "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. // 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 // The static spec has the highest priority, and its paths and definitions won't get overlapped by
// and output share data structures. // 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 { 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. // create shallow copy of staticSpec, but replace paths and definitions because we modify them.
specToReturn := *staticSpec specToReturn := *staticSpec
if staticSpec.Definitions != nil { 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 { 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. // 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) 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{}) { func (c *Controller) addCustomResourceDefinition(obj interface{}) {