mirror of https://github.com/k3s-io/k3s
Update Godep for kube-openapi
parent
76e24f216f
commit
72ce8773a4
|
@ -3099,27 +3099,27 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/kube-openapi/pkg/aggregator",
|
||||
"Rev": "80f07ef71bb4f781233c65aa8d0369e4ecafab87"
|
||||
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/kube-openapi/pkg/builder",
|
||||
"Rev": "80f07ef71bb4f781233c65aa8d0369e4ecafab87"
|
||||
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/kube-openapi/pkg/common",
|
||||
"Rev": "80f07ef71bb4f781233c65aa8d0369e4ecafab87"
|
||||
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/kube-openapi/pkg/generators",
|
||||
"Rev": "80f07ef71bb4f781233c65aa8d0369e4ecafab87"
|
||||
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/kube-openapi/pkg/handler",
|
||||
"Rev": "80f07ef71bb4f781233c65aa8d0369e4ecafab87"
|
||||
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/kube-openapi/pkg/util",
|
||||
"Rev": "80f07ef71bb4f781233c65aa8d0369e4ecafab87"
|
||||
"Rev": "868f2f29720b192240e18284659231b440f9cda5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/utils/exec",
|
||||
|
|
|
@ -154,8 +154,28 @@ func (s *referenceWalker) Start() {
|
|||
}
|
||||
}
|
||||
|
||||
// FilterSpecByPaths remove unnecessary paths and unused definitions.
|
||||
// usedDefinitionForSpec returns a map with all used definition in the provided spec as keys and true as values.
|
||||
func usedDefinitionForSpec(sp *spec.Swagger) map[string]bool {
|
||||
usedDefinitions := map[string]bool{}
|
||||
walkOnAllReferences(func(ref spec.Ref) spec.Ref {
|
||||
if refStr := ref.String(); refStr != "" && strings.HasPrefix(refStr, definitionPrefix) {
|
||||
usedDefinitions[refStr[len(definitionPrefix):]] = true
|
||||
}
|
||||
return ref
|
||||
}, sp)
|
||||
return usedDefinitions
|
||||
}
|
||||
|
||||
// FilterSpecByPaths removes unnecessary paths and definitions used by those paths.
|
||||
// i.e. if a Path removed by this function, all definition used by it and not used
|
||||
// anywhere else will also be removed.
|
||||
func FilterSpecByPaths(sp *spec.Swagger, keepPathPrefixes []string) {
|
||||
// Walk all references to find all used definitions. This function
|
||||
// want to only deal with unused definitions resulted from filtering paths.
|
||||
// Thus a definition will be removed only if it has been used before but
|
||||
// it is unused because of a path prune.
|
||||
initialUsedDefinitions := usedDefinitionForSpec(sp)
|
||||
|
||||
// First remove unwanted paths
|
||||
prefixes := util.NewTrie(keepPathPrefixes)
|
||||
orgPaths := sp.Paths
|
||||
|
@ -174,34 +194,24 @@ func FilterSpecByPaths(sp *spec.Swagger, keepPathPrefixes []string) {
|
|||
}
|
||||
|
||||
// Walk all references to find all definition references.
|
||||
usedDefinitions := map[string]bool{}
|
||||
|
||||
walkOnAllReferences(func(ref spec.Ref) spec.Ref {
|
||||
if ref.String() != "" {
|
||||
refStr := ref.String()
|
||||
if strings.HasPrefix(refStr, definitionPrefix) {
|
||||
usedDefinitions[refStr[len(definitionPrefix):]] = true
|
||||
}
|
||||
}
|
||||
return ref
|
||||
}, sp)
|
||||
usedDefinitions := usedDefinitionForSpec(sp)
|
||||
|
||||
// Remove unused definitions
|
||||
orgDefinitions := sp.Definitions
|
||||
sp.Definitions = spec.Definitions{}
|
||||
for k, v := range orgDefinitions {
|
||||
if usedDefinitions[k] {
|
||||
if usedDefinitions[k] || !initialUsedDefinitions[k] {
|
||||
sp.Definitions[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func renameDefinition(s *spec.Swagger, old, new string) {
|
||||
old_ref := definitionPrefix + old
|
||||
new_ref := definitionPrefix + new
|
||||
oldRef := definitionPrefix + old
|
||||
newRef := definitionPrefix + new
|
||||
walkOnAllReferences(func(ref spec.Ref) spec.Ref {
|
||||
if ref.String() == old_ref {
|
||||
return spec.MustCreateRef(new_ref)
|
||||
if ref.String() == oldRef {
|
||||
return spec.MustCreateRef(newRef)
|
||||
}
|
||||
return ref
|
||||
}, s)
|
||||
|
@ -209,58 +219,117 @@ func renameDefinition(s *spec.Swagger, old, new string) {
|
|||
delete(s.Definitions, old)
|
||||
}
|
||||
|
||||
// Copy paths and definitions from source to dest, rename definitions if needed.
|
||||
// dest will be mutated, and source will not be changed.
|
||||
// MergeSpecsIgnorePathConflict is the same as MergeSpecs except it will ignore any path
|
||||
// conflicts by keeping the paths of destination. It will rename definition conflicts.
|
||||
func MergeSpecsIgnorePathConflict(dest, source *spec.Swagger) error {
|
||||
return mergeSpecs(dest, source, true, true)
|
||||
}
|
||||
|
||||
// MergeSpecsFailOnDefinitionConflict is differ from MergeSpecs as it fails if there is
|
||||
// a definition conflict.
|
||||
func MergeSpecsFailOnDefinitionConflict(dest, source *spec.Swagger) error {
|
||||
return mergeSpecs(dest, source, false, false)
|
||||
}
|
||||
|
||||
// MergeSpecs copies paths and definitions from source to dest, rename definitions if needed.
|
||||
// dest will be mutated, and source will not be changed. It will fail on path conflicts.
|
||||
func MergeSpecs(dest, source *spec.Swagger) error {
|
||||
sourceCopy, err := CloneSpec(source)
|
||||
if err != nil {
|
||||
return err
|
||||
return mergeSpecs(dest, source, true, false)
|
||||
}
|
||||
|
||||
func mergeSpecs(dest, source *spec.Swagger, renameModelConflicts, ignorePathConflicts bool) (err error) {
|
||||
specCloned := false
|
||||
if ignorePathConflicts {
|
||||
keepPaths := []string{}
|
||||
hasConflictingPath := false
|
||||
for k := range source.Paths.Paths {
|
||||
if _, found := dest.Paths.Paths[k]; !found {
|
||||
keepPaths = append(keepPaths, k)
|
||||
} else {
|
||||
hasConflictingPath = true
|
||||
}
|
||||
}
|
||||
if len(keepPaths) == 0 {
|
||||
// There is nothing to merge. All paths are conflicting.
|
||||
return nil
|
||||
}
|
||||
if hasConflictingPath {
|
||||
source, err = CloneSpec(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
specCloned = true
|
||||
FilterSpecByPaths(source, keepPaths)
|
||||
}
|
||||
}
|
||||
for k, v := range sourceCopy.Paths.Paths {
|
||||
// Check for model conflicts
|
||||
conflicts := false
|
||||
for k, v := range source.Definitions {
|
||||
v2, found := dest.Definitions[k]
|
||||
if found && !reflect.DeepEqual(v, v2) {
|
||||
if !renameModelConflicts {
|
||||
return fmt.Errorf("model name conflict in merging OpenAPI spec: %s", k)
|
||||
}
|
||||
conflicts = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if conflicts {
|
||||
if !specCloned {
|
||||
source, err = CloneSpec(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
specCloned = true
|
||||
usedNames := map[string]bool{}
|
||||
for k := range dest.Definitions {
|
||||
usedNames[k] = true
|
||||
}
|
||||
type Rename struct {
|
||||
from, to string
|
||||
}
|
||||
renames := []Rename{}
|
||||
for k, v := range source.Definitions {
|
||||
if usedNames[k] {
|
||||
v2, found := dest.Definitions[k]
|
||||
// Reuse model iff they are exactly the same.
|
||||
if found && reflect.DeepEqual(v, v2) {
|
||||
continue
|
||||
}
|
||||
i := 2
|
||||
newName := fmt.Sprintf("%s_v%d", k, i)
|
||||
_, foundInSource := source.Definitions[newName]
|
||||
for usedNames[newName] || foundInSource {
|
||||
i++
|
||||
newName = fmt.Sprintf("%s_v%d", k, i)
|
||||
_, foundInSource = source.Definitions[newName]
|
||||
}
|
||||
renames = append(renames, Rename{from: k, to: newName})
|
||||
usedNames[newName] = true
|
||||
}
|
||||
}
|
||||
for _, r := range renames {
|
||||
renameDefinition(source, r.from, r.to)
|
||||
}
|
||||
}
|
||||
for k, v := range source.Definitions {
|
||||
if _, found := dest.Definitions[k]; !found {
|
||||
dest.Definitions[k] = v
|
||||
}
|
||||
}
|
||||
// Check for path conflicts
|
||||
for k, v := range source.Paths.Paths {
|
||||
if _, found := dest.Paths.Paths[k]; found {
|
||||
return fmt.Errorf("unable to merge: duplicated path %s", k)
|
||||
}
|
||||
dest.Paths.Paths[k] = v
|
||||
}
|
||||
usedNames := map[string]bool{}
|
||||
for k := range dest.Definitions {
|
||||
usedNames[k] = true
|
||||
}
|
||||
type Rename struct {
|
||||
from, to string
|
||||
}
|
||||
renames := []Rename{}
|
||||
for k, v := range sourceCopy.Definitions {
|
||||
if usedNames[k] {
|
||||
v2, found := dest.Definitions[k]
|
||||
// Reuse model iff they are exactly the same.
|
||||
if found && reflect.DeepEqual(v, v2) {
|
||||
continue
|
||||
}
|
||||
i := 2
|
||||
newName := fmt.Sprintf("%s_v%d", k, i)
|
||||
_, foundInSource := sourceCopy.Definitions[newName]
|
||||
for usedNames[newName] || foundInSource {
|
||||
i += 1
|
||||
newName = fmt.Sprintf("%s_v%d", k, i)
|
||||
_, foundInSource = sourceCopy.Definitions[newName]
|
||||
}
|
||||
renames = append(renames, Rename{from: k, to: newName})
|
||||
usedNames[newName] = true
|
||||
}
|
||||
}
|
||||
for _, r := range renames {
|
||||
renameDefinition(sourceCopy, r.from, r.to)
|
||||
}
|
||||
for k, v := range sourceCopy.Definitions {
|
||||
if _, found := dest.Definitions[k]; !found {
|
||||
dest.Definitions[k] = v
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Clone OpenAPI spec
|
||||
// CloneSpec clones OpenAPI spec
|
||||
func CloneSpec(source *spec.Swagger) (*spec.Swagger, error) {
|
||||
// TODO(mehdy): Find a faster way to clone an spec
|
||||
bytes, err := json.Marshal(source)
|
||||
|
|
|
@ -328,6 +328,7 @@ func (g openAPITypeWriter) generateMembers(t *types.Type, required []string) ([]
|
|||
required = append(required, name)
|
||||
}
|
||||
if err = g.generateProperty(&m, t); err != nil {
|
||||
glog.Errorf("Error when generating: %v, %v\n", name, m)
|
||||
return required, err
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue