...
1
16
17 package aggregator
18
19 import (
20 "strings"
21
22 "k8s.io/kube-openapi/pkg/validation/spec"
23 )
24
25 const (
26 definitionPrefix = "#/definitions/"
27 parameterPrefix = "#/parameters/"
28 )
29
30
31 type readonlyReferenceWalker struct {
32
33 walkRefCallback func(ref *spec.Ref)
34
35
36 root *spec.Swagger
37 }
38
39
40
41 func walkOnAllReferences(walkRef func(ref *spec.Ref), root *spec.Swagger) {
42 alreadyVisited := map[string]bool{}
43
44 walker := &readonlyReferenceWalker{
45 root: root,
46 }
47 walker.walkRefCallback = func(ref *spec.Ref) {
48 walkRef(ref)
49
50 refStr := ref.String()
51 if refStr == "" || !strings.HasPrefix(refStr, definitionPrefix) {
52 return
53 }
54 defName := refStr[len(definitionPrefix):]
55
56 if _, found := root.Definitions[defName]; found && !alreadyVisited[refStr] {
57 alreadyVisited[refStr] = true
58 def := root.Definitions[defName]
59 walker.walkSchema(&def)
60 }
61 }
62 walker.Start()
63 }
64
65 func (s *readonlyReferenceWalker) walkSchema(schema *spec.Schema) {
66 if schema == nil {
67 return
68 }
69 s.walkRefCallback(&schema.Ref)
70 var v *spec.Schema
71 if len(schema.Definitions)+len(schema.Properties)+len(schema.PatternProperties) > 0 {
72 v = &spec.Schema{}
73 }
74 for k := range schema.Definitions {
75 *v = schema.Definitions[k]
76 s.walkSchema(v)
77 }
78 for k := range schema.Properties {
79 *v = schema.Properties[k]
80 s.walkSchema(v)
81 }
82 for k := range schema.PatternProperties {
83 *v = schema.PatternProperties[k]
84 s.walkSchema(v)
85 }
86 for i := range schema.AllOf {
87 s.walkSchema(&schema.AllOf[i])
88 }
89 for i := range schema.AnyOf {
90 s.walkSchema(&schema.AnyOf[i])
91 }
92 for i := range schema.OneOf {
93 s.walkSchema(&schema.OneOf[i])
94 }
95 if schema.Not != nil {
96 s.walkSchema(schema.Not)
97 }
98 if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil {
99 s.walkSchema(schema.AdditionalProperties.Schema)
100 }
101 if schema.AdditionalItems != nil && schema.AdditionalItems.Schema != nil {
102 s.walkSchema(schema.AdditionalItems.Schema)
103 }
104 if schema.Items != nil {
105 if schema.Items.Schema != nil {
106 s.walkSchema(schema.Items.Schema)
107 }
108 for i := range schema.Items.Schemas {
109 s.walkSchema(&schema.Items.Schemas[i])
110 }
111 }
112 }
113
114 func (s *readonlyReferenceWalker) walkParams(params []spec.Parameter) {
115 if params == nil {
116 return
117 }
118 for _, param := range params {
119 s.walkRefCallback(¶m.Ref)
120 s.walkSchema(param.Schema)
121 if param.Items != nil {
122 s.walkRefCallback(¶m.Items.Ref)
123 }
124 }
125 }
126
127 func (s *readonlyReferenceWalker) walkResponse(resp *spec.Response) {
128 if resp == nil {
129 return
130 }
131 s.walkRefCallback(&resp.Ref)
132 s.walkSchema(resp.Schema)
133 }
134
135 func (s *readonlyReferenceWalker) walkOperation(op *spec.Operation) {
136 if op == nil {
137 return
138 }
139 s.walkParams(op.Parameters)
140 if op.Responses == nil {
141 return
142 }
143 s.walkResponse(op.Responses.Default)
144 for _, r := range op.Responses.StatusCodeResponses {
145 s.walkResponse(&r)
146 }
147 }
148
149 func (s *readonlyReferenceWalker) Start() {
150 if s.root.Paths == nil {
151 return
152 }
153 for _, pathItem := range s.root.Paths.Paths {
154 s.walkParams(pathItem.Parameters)
155 s.walkOperation(pathItem.Delete)
156 s.walkOperation(pathItem.Get)
157 s.walkOperation(pathItem.Head)
158 s.walkOperation(pathItem.Options)
159 s.walkOperation(pathItem.Patch)
160 s.walkOperation(pathItem.Post)
161 s.walkOperation(pathItem.Put)
162 }
163 }
164
View as plain text