gnostic.go 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517
  1. /*
  2. Copyright 2022 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package spec
  14. import (
  15. "errors"
  16. "strconv"
  17. "github.com/go-openapi/jsonreference"
  18. openapi_v2 "github.com/google/gnostic-models/openapiv2"
  19. )
  20. // Interfaces
  21. type GnosticCommonValidations interface {
  22. GetMaximum() float64
  23. GetExclusiveMaximum() bool
  24. GetMinimum() float64
  25. GetExclusiveMinimum() bool
  26. GetMaxLength() int64
  27. GetMinLength() int64
  28. GetPattern() string
  29. GetMaxItems() int64
  30. GetMinItems() int64
  31. GetUniqueItems() bool
  32. GetMultipleOf() float64
  33. GetEnum() []*openapi_v2.Any
  34. }
  35. func (k *CommonValidations) FromGnostic(g GnosticCommonValidations) error {
  36. if g == nil {
  37. return nil
  38. }
  39. max := g.GetMaximum()
  40. if max != 0 {
  41. k.Maximum = &max
  42. }
  43. k.ExclusiveMaximum = g.GetExclusiveMaximum()
  44. min := g.GetMinimum()
  45. if min != 0 {
  46. k.Minimum = &min
  47. }
  48. k.ExclusiveMinimum = g.GetExclusiveMinimum()
  49. maxLen := g.GetMaxLength()
  50. if maxLen != 0 {
  51. k.MaxLength = &maxLen
  52. }
  53. minLen := g.GetMinLength()
  54. if minLen != 0 {
  55. k.MinLength = &minLen
  56. }
  57. k.Pattern = g.GetPattern()
  58. maxItems := g.GetMaxItems()
  59. if maxItems != 0 {
  60. k.MaxItems = &maxItems
  61. }
  62. minItems := g.GetMinItems()
  63. if minItems != 0 {
  64. k.MinItems = &minItems
  65. }
  66. k.UniqueItems = g.GetUniqueItems()
  67. multOf := g.GetMultipleOf()
  68. if multOf != 0 {
  69. k.MultipleOf = &multOf
  70. }
  71. enums := g.GetEnum()
  72. if enums != nil {
  73. k.Enum = make([]interface{}, len(enums))
  74. for i, v := range enums {
  75. if v == nil {
  76. continue
  77. }
  78. var convert interface{}
  79. if err := v.ToRawInfo().Decode(&convert); err != nil {
  80. return err
  81. } else {
  82. k.Enum[i] = convert
  83. }
  84. }
  85. }
  86. return nil
  87. }
  88. type GnosticSimpleSchema interface {
  89. GetType() string
  90. GetFormat() string
  91. GetItems() *openapi_v2.PrimitivesItems
  92. GetCollectionFormat() string
  93. GetDefault() *openapi_v2.Any
  94. }
  95. func (k *SimpleSchema) FromGnostic(g GnosticSimpleSchema) error {
  96. if g == nil {
  97. return nil
  98. }
  99. k.Type = g.GetType()
  100. k.Format = g.GetFormat()
  101. k.CollectionFormat = g.GetCollectionFormat()
  102. items := g.GetItems()
  103. if items != nil {
  104. k.Items = &Items{}
  105. if err := k.Items.FromGnostic(items); err != nil {
  106. return err
  107. }
  108. }
  109. def := g.GetDefault()
  110. if def != nil {
  111. var convert interface{}
  112. if err := def.ToRawInfo().Decode(&convert); err != nil {
  113. return err
  114. } else {
  115. k.Default = convert
  116. }
  117. }
  118. return nil
  119. }
  120. func (k *Items) FromGnostic(g *openapi_v2.PrimitivesItems) error {
  121. if g == nil {
  122. return nil
  123. }
  124. if err := k.SimpleSchema.FromGnostic(g); err != nil {
  125. return err
  126. }
  127. if err := k.CommonValidations.FromGnostic(g); err != nil {
  128. return err
  129. }
  130. if err := k.VendorExtensible.FromGnostic(g.VendorExtension); err != nil {
  131. return err
  132. }
  133. return nil
  134. }
  135. func (k *VendorExtensible) FromGnostic(g []*openapi_v2.NamedAny) error {
  136. if len(g) == 0 {
  137. return nil
  138. }
  139. k.Extensions = make(Extensions, len(g))
  140. for _, v := range g {
  141. if v == nil {
  142. continue
  143. }
  144. if v.Value == nil {
  145. k.Extensions[v.Name] = nil
  146. continue
  147. }
  148. var iface interface{}
  149. if err := v.Value.ToRawInfo().Decode(&iface); err != nil {
  150. return err
  151. } else {
  152. k.Extensions[v.Name] = iface
  153. }
  154. }
  155. return nil
  156. }
  157. func (k *Refable) FromGnostic(g string) error {
  158. return k.Ref.FromGnostic(g)
  159. }
  160. func (k *Ref) FromGnostic(g string) error {
  161. if g == "" {
  162. return nil
  163. }
  164. ref, err := jsonreference.New(g)
  165. if err != nil {
  166. return err
  167. }
  168. *k = Ref{
  169. Ref: ref,
  170. }
  171. return nil
  172. }
  173. // Converts a gnostic v2 Document to a kube-openapi Swagger Document
  174. //
  175. // Caveats:
  176. //
  177. // - gnostic v2 documents treats zero as unspecified for numerical fields of
  178. // CommonValidations fields such as Maximum, Minimum, MaximumItems, etc.
  179. // There will always be data loss if one of the values of these fields is set to zero.
  180. //
  181. // Returns:
  182. //
  183. // - `ok`: `false` if a value was present in the gnostic document which cannot be
  184. // roundtripped into kube-openapi types. In these instances, `ok` is set to
  185. // `false` and the value is skipped.
  186. //
  187. // - `err`: an unexpected error occurred in the conversion from the gnostic type
  188. // to kube-openapi type.
  189. func (k *Swagger) FromGnostic(g *openapi_v2.Document) (ok bool, err error) {
  190. ok = true
  191. if g == nil {
  192. return true, nil
  193. }
  194. if err := k.VendorExtensible.FromGnostic(g.VendorExtension); err != nil {
  195. return false, err
  196. }
  197. if nok, err := k.SwaggerProps.FromGnostic(g); err != nil {
  198. return false, err
  199. } else if !nok {
  200. ok = false
  201. }
  202. return ok, nil
  203. }
  204. func (k *SwaggerProps) FromGnostic(g *openapi_v2.Document) (ok bool, err error) {
  205. if g == nil {
  206. return true, nil
  207. }
  208. ok = true
  209. // openapi_v2.Document does not support "ID" field, so it will not be
  210. // included
  211. k.Consumes = g.Consumes
  212. k.Produces = g.Produces
  213. k.Schemes = g.Schemes
  214. k.Swagger = g.Swagger
  215. if g.Info != nil {
  216. k.Info = &Info{}
  217. if nok, err := k.Info.FromGnostic(g.Info); err != nil {
  218. return false, err
  219. } else if !nok {
  220. ok = false
  221. }
  222. }
  223. k.Host = g.Host
  224. k.BasePath = g.BasePath
  225. if g.Paths != nil {
  226. k.Paths = &Paths{}
  227. if nok, err := k.Paths.FromGnostic(g.Paths); err != nil {
  228. return false, err
  229. } else if !nok {
  230. ok = false
  231. }
  232. }
  233. if g.Definitions != nil {
  234. k.Definitions = make(Definitions, len(g.Definitions.AdditionalProperties))
  235. for _, v := range g.Definitions.AdditionalProperties {
  236. if v == nil {
  237. continue
  238. }
  239. converted := Schema{}
  240. if nok, err := converted.FromGnostic(v.Value); err != nil {
  241. return false, err
  242. } else if !nok {
  243. ok = false
  244. }
  245. k.Definitions[v.Name] = converted
  246. }
  247. }
  248. if g.Parameters != nil {
  249. k.Parameters = make(
  250. map[string]Parameter,
  251. len(g.Parameters.AdditionalProperties))
  252. for _, v := range g.Parameters.AdditionalProperties {
  253. if v == nil {
  254. continue
  255. }
  256. p := Parameter{}
  257. if nok, err := p.FromGnostic(v.Value); err != nil {
  258. return false, err
  259. } else if !nok {
  260. ok = false
  261. }
  262. k.Parameters[v.Name] = p
  263. }
  264. }
  265. if g.Responses != nil {
  266. k.Responses = make(
  267. map[string]Response,
  268. len(g.Responses.AdditionalProperties))
  269. for _, v := range g.Responses.AdditionalProperties {
  270. if v == nil {
  271. continue
  272. }
  273. p := Response{}
  274. if nok, err := p.FromGnostic(v.Value); err != nil {
  275. return false, err
  276. } else if !nok {
  277. ok = false
  278. }
  279. k.Responses[v.Name] = p
  280. }
  281. }
  282. if g.SecurityDefinitions != nil {
  283. k.SecurityDefinitions = make(SecurityDefinitions)
  284. if err := k.SecurityDefinitions.FromGnostic(g.SecurityDefinitions); err != nil {
  285. return false, err
  286. }
  287. }
  288. if g.Security != nil {
  289. k.Security = make([]map[string][]string, len(g.Security))
  290. for i, v := range g.Security {
  291. if v == nil || v.AdditionalProperties == nil {
  292. continue
  293. }
  294. k.Security[i] = make(map[string][]string, len(v.AdditionalProperties))
  295. converted := k.Security[i]
  296. for _, p := range v.AdditionalProperties {
  297. if p == nil {
  298. continue
  299. }
  300. if p.Value != nil {
  301. converted[p.Name] = p.Value.Value
  302. } else {
  303. converted[p.Name] = nil
  304. }
  305. }
  306. }
  307. }
  308. if g.Tags != nil {
  309. k.Tags = make([]Tag, len(g.Tags))
  310. for i, v := range g.Tags {
  311. if v == nil {
  312. continue
  313. } else if nok, err := k.Tags[i].FromGnostic(v); err != nil {
  314. return false, err
  315. } else if !nok {
  316. ok = false
  317. }
  318. }
  319. }
  320. if g.ExternalDocs != nil {
  321. k.ExternalDocs = &ExternalDocumentation{}
  322. if nok, err := k.ExternalDocs.FromGnostic(g.ExternalDocs); err != nil {
  323. return false, err
  324. } else if !nok {
  325. ok = false
  326. }
  327. }
  328. return ok, nil
  329. }
  330. // Info
  331. func (k *Info) FromGnostic(g *openapi_v2.Info) (ok bool, err error) {
  332. ok = true
  333. if g == nil {
  334. return true, nil
  335. }
  336. if err := k.VendorExtensible.FromGnostic(g.VendorExtension); err != nil {
  337. return false, err
  338. }
  339. if nok, err := k.InfoProps.FromGnostic(g); err != nil {
  340. return false, err
  341. } else if !nok {
  342. ok = false
  343. }
  344. return ok, nil
  345. }
  346. func (k *InfoProps) FromGnostic(g *openapi_v2.Info) (ok bool, err error) {
  347. if g == nil {
  348. return true, nil
  349. }
  350. ok = true
  351. k.Description = g.Description
  352. k.Title = g.Title
  353. k.TermsOfService = g.TermsOfService
  354. if g.Contact != nil {
  355. k.Contact = &ContactInfo{}
  356. if nok, err := k.Contact.FromGnostic(g.Contact); err != nil {
  357. return false, err
  358. } else if !nok {
  359. ok = false
  360. }
  361. }
  362. if g.License != nil {
  363. k.License = &License{}
  364. if nok, err := k.License.FromGnostic(g.License); err != nil {
  365. return false, err
  366. } else if !nok {
  367. ok = false
  368. }
  369. }
  370. k.Version = g.Version
  371. return ok, nil
  372. }
  373. func (k *License) FromGnostic(g *openapi_v2.License) (ok bool, err error) {
  374. if g == nil {
  375. return true, nil
  376. }
  377. ok = true
  378. k.Name = g.Name
  379. k.URL = g.Url
  380. // License does not embed to VendorExtensible!
  381. // data loss from g.VendorExtension
  382. if len(g.VendorExtension) != 0 {
  383. ok = false
  384. }
  385. return ok, nil
  386. }
  387. func (k *ContactInfo) FromGnostic(g *openapi_v2.Contact) (ok bool, err error) {
  388. if g == nil {
  389. return true, nil
  390. }
  391. ok = true
  392. k.Name = g.Name
  393. k.URL = g.Url
  394. k.Email = g.Email
  395. // ContactInfo does not embed to VendorExtensible!
  396. // data loss from g.VendorExtension
  397. if len(g.VendorExtension) != 0 {
  398. ok = false
  399. }
  400. return ok, nil
  401. }
  402. // Paths
  403. func (k *Paths) FromGnostic(g *openapi_v2.Paths) (ok bool, err error) {
  404. if g == nil {
  405. return true, nil
  406. }
  407. ok = true
  408. if g.Path != nil {
  409. k.Paths = make(map[string]PathItem, len(g.Path))
  410. for _, v := range g.Path {
  411. if v == nil {
  412. continue
  413. }
  414. converted := PathItem{}
  415. if nok, err := converted.FromGnostic(v.Value); err != nil {
  416. return false, err
  417. } else if !nok {
  418. ok = false
  419. }
  420. k.Paths[v.Name] = converted
  421. }
  422. }
  423. if err := k.VendorExtensible.FromGnostic(g.VendorExtension); err != nil {
  424. return false, err
  425. }
  426. return ok, nil
  427. }
  428. func (k *PathItem) FromGnostic(g *openapi_v2.PathItem) (ok bool, err error) {
  429. if g == nil {
  430. return true, nil
  431. }
  432. ok = true
  433. if nok, err := k.PathItemProps.FromGnostic(g); err != nil {
  434. return false, err
  435. } else if !nok {
  436. ok = false
  437. }
  438. if err := k.Refable.FromGnostic(g.XRef); err != nil {
  439. return false, err
  440. }
  441. if err := k.VendorExtensible.FromGnostic(g.VendorExtension); err != nil {
  442. return false, err
  443. }
  444. return ok, nil
  445. }
  446. func (k *PathItemProps) FromGnostic(g *openapi_v2.PathItem) (ok bool, err error) {
  447. if g == nil {
  448. return true, nil
  449. }
  450. ok = true
  451. if g.Get != nil {
  452. k.Get = &Operation{}
  453. if nok, err := k.Get.FromGnostic(g.Get); err != nil {
  454. return false, err
  455. } else if !nok {
  456. ok = false
  457. }
  458. }
  459. if g.Put != nil {
  460. k.Put = &Operation{}
  461. if nok, err := k.Put.FromGnostic(g.Put); err != nil {
  462. return false, err
  463. } else if !nok {
  464. ok = false
  465. }
  466. }
  467. if g.Post != nil {
  468. k.Post = &Operation{}
  469. if nok, err := k.Post.FromGnostic(g.Post); err != nil {
  470. return false, err
  471. } else if !nok {
  472. ok = false
  473. }
  474. }
  475. if g.Delete != nil {
  476. k.Delete = &Operation{}
  477. if nok, err := k.Delete.FromGnostic(g.Delete); err != nil {
  478. return false, err
  479. } else if !nok {
  480. ok = false
  481. }
  482. }
  483. if g.Options != nil {
  484. k.Options = &Operation{}
  485. if nok, err := k.Options.FromGnostic(g.Options); err != nil {
  486. return false, err
  487. } else if !nok {
  488. ok = false
  489. }
  490. }
  491. if g.Head != nil {
  492. k.Head = &Operation{}
  493. if nok, err := k.Head.FromGnostic(g.Head); err != nil {
  494. return false, err
  495. } else if !nok {
  496. ok = false
  497. }
  498. }
  499. if g.Patch != nil {
  500. k.Patch = &Operation{}
  501. if nok, err := k.Patch.FromGnostic(g.Patch); err != nil {
  502. return false, err
  503. } else if !nok {
  504. ok = false
  505. }
  506. }
  507. if g.Parameters != nil {
  508. k.Parameters = make([]Parameter, len(g.Parameters))
  509. for i, v := range g.Parameters {
  510. if v == nil {
  511. continue
  512. } else if nok, err := k.Parameters[i].FromGnosticParametersItem(v); err != nil {
  513. return false, err
  514. } else if !nok {
  515. ok = false
  516. }
  517. }
  518. }
  519. return ok, nil
  520. }
  521. func (k *Operation) FromGnostic(g *openapi_v2.Operation) (ok bool, err error) {
  522. if g == nil {
  523. return true, nil
  524. }
  525. ok = true
  526. if err := k.VendorExtensible.FromGnostic(g.VendorExtension); err != nil {
  527. return false, err
  528. }
  529. if nok, err := k.OperationProps.FromGnostic(g); err != nil {
  530. return false, err
  531. } else if !nok {
  532. ok = false
  533. }
  534. return ok, nil
  535. }
  536. func (k *OperationProps) FromGnostic(g *openapi_v2.Operation) (ok bool, err error) {
  537. if g == nil {
  538. return true, nil
  539. }
  540. ok = true
  541. k.Description = g.Description
  542. k.Consumes = g.Consumes
  543. k.Produces = g.Produces
  544. k.Schemes = g.Schemes
  545. k.Tags = g.Tags
  546. k.Summary = g.Summary
  547. if g.ExternalDocs != nil {
  548. k.ExternalDocs = &ExternalDocumentation{}
  549. if nok, err := k.ExternalDocs.FromGnostic(g.ExternalDocs); err != nil {
  550. return false, err
  551. } else if !nok {
  552. ok = false
  553. }
  554. }
  555. k.ID = g.OperationId
  556. k.Deprecated = g.Deprecated
  557. if g.Security != nil {
  558. k.Security = make([]map[string][]string, len(g.Security))
  559. for i, v := range g.Security {
  560. if v == nil || v.AdditionalProperties == nil {
  561. continue
  562. }
  563. k.Security[i] = make(map[string][]string, len(v.AdditionalProperties))
  564. converted := k.Security[i]
  565. for _, p := range v.AdditionalProperties {
  566. if p == nil {
  567. continue
  568. }
  569. if p.Value != nil {
  570. converted[p.Name] = p.Value.Value
  571. } else {
  572. converted[p.Name] = nil
  573. }
  574. }
  575. }
  576. }
  577. if g.Parameters != nil {
  578. k.Parameters = make([]Parameter, len(g.Parameters))
  579. for i, v := range g.Parameters {
  580. if v == nil {
  581. continue
  582. } else if nok, err := k.Parameters[i].FromGnosticParametersItem(v); err != nil {
  583. return false, err
  584. } else if !nok {
  585. ok = false
  586. }
  587. }
  588. }
  589. if g.Responses != nil {
  590. k.Responses = &Responses{}
  591. if nok, err := k.Responses.FromGnostic(g.Responses); err != nil {
  592. return false, err
  593. } else if !nok {
  594. ok = false
  595. }
  596. }
  597. return ok, nil
  598. }
  599. // Responses
  600. func (k *Responses) FromGnostic(g *openapi_v2.Responses) (ok bool, err error) {
  601. if g == nil {
  602. return true, nil
  603. }
  604. ok = true
  605. if err := k.VendorExtensible.FromGnostic(g.VendorExtension); err != nil {
  606. return false, err
  607. }
  608. if nok, err := k.ResponsesProps.FromGnostic(g); err != nil {
  609. return false, err
  610. } else if !nok {
  611. ok = false
  612. }
  613. return ok, nil
  614. }
  615. func (k *ResponsesProps) FromGnostic(g *openapi_v2.Responses) (ok bool, err error) {
  616. if g == nil {
  617. return true, nil
  618. } else if g.ResponseCode == nil {
  619. return ok, nil
  620. }
  621. ok = true
  622. for _, v := range g.ResponseCode {
  623. if v == nil {
  624. continue
  625. }
  626. if v.Name == "default" {
  627. k.Default = &Response{}
  628. if nok, err := k.Default.FromGnosticResponseValue(v.Value); err != nil {
  629. return false, err
  630. } else if !nok {
  631. ok = false
  632. }
  633. } else if nk, err := strconv.Atoi(v.Name); err != nil {
  634. // This should actually never fail, unless gnostic struct was
  635. // manually/purposefully tampered with at runtime.
  636. // Gnostic's ParseDocument validates that all StatusCodeResponses
  637. // keys adhere to the following regex ^([0-9]{3})$|^(default)$
  638. ok = false
  639. } else {
  640. if k.StatusCodeResponses == nil {
  641. k.StatusCodeResponses = map[int]Response{}
  642. }
  643. res := Response{}
  644. if nok, err := res.FromGnosticResponseValue(v.Value); err != nil {
  645. return false, err
  646. } else if !nok {
  647. ok = false
  648. }
  649. k.StatusCodeResponses[nk] = res
  650. }
  651. }
  652. return ok, nil
  653. }
  654. func (k *Response) FromGnostic(g *openapi_v2.Response) (ok bool, err error) {
  655. if g == nil {
  656. return true, nil
  657. }
  658. ok = true
  659. // Refable case handled in FromGnosticResponseValue
  660. if err := k.VendorExtensible.FromGnostic(g.VendorExtension); err != nil {
  661. return false, err
  662. }
  663. if nok, err := k.ResponseProps.FromGnostic(g); err != nil {
  664. return false, err
  665. } else if !nok {
  666. ok = false
  667. }
  668. return ok, nil
  669. }
  670. func (k *Response) FromGnosticResponseValue(g *openapi_v2.ResponseValue) (ok bool, err error) {
  671. ok = true
  672. if ref := g.GetJsonReference(); ref != nil {
  673. k.Description = ref.Description
  674. if err := k.Refable.FromGnostic(ref.XRef); err != nil {
  675. return false, err
  676. }
  677. } else if nok, err := k.FromGnostic(g.GetResponse()); err != nil {
  678. return false, err
  679. } else if !nok {
  680. ok = false
  681. }
  682. return ok, nil
  683. }
  684. func (k *ResponseProps) FromGnostic(g *openapi_v2.Response) (ok bool, err error) {
  685. if g == nil {
  686. return true, nil
  687. }
  688. ok = true
  689. k.Description = g.Description
  690. if g.Schema != nil {
  691. k.Schema = &Schema{}
  692. if nok, err := k.Schema.FromGnosticSchemaItem(g.Schema); err != nil {
  693. return false, err
  694. } else if !nok {
  695. ok = false
  696. }
  697. }
  698. if g.Headers != nil {
  699. k.Headers = make(map[string]Header, len(g.Headers.AdditionalProperties))
  700. for _, v := range g.Headers.AdditionalProperties {
  701. if v == nil {
  702. continue
  703. }
  704. converted := Header{}
  705. if err := converted.FromGnostic(v.GetValue()); err != nil {
  706. return false, err
  707. }
  708. k.Headers[v.Name] = converted
  709. }
  710. }
  711. if g.Examples != nil {
  712. k.Examples = make(map[string]interface{}, len(g.Examples.AdditionalProperties))
  713. for _, v := range g.Examples.AdditionalProperties {
  714. if v == nil {
  715. continue
  716. } else if v.Value == nil {
  717. k.Examples[v.Name] = nil
  718. continue
  719. }
  720. var iface interface{}
  721. if err := v.Value.ToRawInfo().Decode(&iface); err != nil {
  722. return false, err
  723. } else {
  724. k.Examples[v.Name] = iface
  725. }
  726. }
  727. }
  728. return ok, nil
  729. }
  730. // Header
  731. func (k *Header) FromGnostic(g *openapi_v2.Header) (err error) {
  732. if g == nil {
  733. return nil
  734. }
  735. if err := k.CommonValidations.FromGnostic(g); err != nil {
  736. return err
  737. }
  738. if err := k.VendorExtensible.FromGnostic(g.VendorExtension); err != nil {
  739. return err
  740. }
  741. if err := k.SimpleSchema.FromGnostic(g); err != nil {
  742. return err
  743. }
  744. if err := k.HeaderProps.FromGnostic(g); err != nil {
  745. return err
  746. }
  747. return nil
  748. }
  749. func (k *HeaderProps) FromGnostic(g *openapi_v2.Header) error {
  750. if g == nil {
  751. return nil
  752. }
  753. // All other fields of openapi_v2.Header are handled by
  754. // the embeded fields, commonvalidations, etc.
  755. k.Description = g.Description
  756. return nil
  757. }
  758. // Parameters
  759. func (k *Parameter) FromGnostic(g *openapi_v2.Parameter) (ok bool, err error) {
  760. if g == nil {
  761. return true, nil
  762. }
  763. ok = true
  764. switch p := g.Oneof.(type) {
  765. case *openapi_v2.Parameter_BodyParameter:
  766. if nok, err := k.ParamProps.FromGnostic(p.BodyParameter); err != nil {
  767. return false, err
  768. } else if !nok {
  769. ok = false
  770. }
  771. if err := k.VendorExtensible.FromGnostic(p.BodyParameter.GetVendorExtension()); err != nil {
  772. return false, err
  773. }
  774. return ok, nil
  775. case *openapi_v2.Parameter_NonBodyParameter:
  776. switch nb := g.GetNonBodyParameter().Oneof.(type) {
  777. case *openapi_v2.NonBodyParameter_HeaderParameterSubSchema:
  778. if nok, err := k.ParamProps.FromGnostic(nb.HeaderParameterSubSchema); err != nil {
  779. return false, err
  780. } else if !nok {
  781. ok = false
  782. }
  783. if err := k.SimpleSchema.FromGnostic(nb.HeaderParameterSubSchema); err != nil {
  784. return false, err
  785. }
  786. if err := k.CommonValidations.FromGnostic(nb.HeaderParameterSubSchema); err != nil {
  787. return false, err
  788. }
  789. if err := k.VendorExtensible.FromGnostic(nb.HeaderParameterSubSchema.GetVendorExtension()); err != nil {
  790. return false, err
  791. }
  792. return ok, nil
  793. case *openapi_v2.NonBodyParameter_FormDataParameterSubSchema:
  794. if nok, err := k.ParamProps.FromGnostic(nb.FormDataParameterSubSchema); err != nil {
  795. return false, err
  796. } else if !nok {
  797. ok = false
  798. }
  799. if err := k.SimpleSchema.FromGnostic(nb.FormDataParameterSubSchema); err != nil {
  800. return false, err
  801. }
  802. if err := k.CommonValidations.FromGnostic(nb.FormDataParameterSubSchema); err != nil {
  803. return false, err
  804. }
  805. if err := k.VendorExtensible.FromGnostic(nb.FormDataParameterSubSchema.GetVendorExtension()); err != nil {
  806. return false, err
  807. }
  808. return ok, nil
  809. case *openapi_v2.NonBodyParameter_QueryParameterSubSchema:
  810. if nok, err := k.ParamProps.FromGnostic(nb.QueryParameterSubSchema); err != nil {
  811. return false, err
  812. } else if !nok {
  813. ok = false
  814. }
  815. if err := k.SimpleSchema.FromGnostic(nb.QueryParameterSubSchema); err != nil {
  816. return false, err
  817. }
  818. if err := k.CommonValidations.FromGnostic(nb.QueryParameterSubSchema); err != nil {
  819. return false, err
  820. }
  821. if err := k.VendorExtensible.FromGnostic(nb.QueryParameterSubSchema.GetVendorExtension()); err != nil {
  822. return false, err
  823. }
  824. return ok, nil
  825. case *openapi_v2.NonBodyParameter_PathParameterSubSchema:
  826. if nok, err := k.ParamProps.FromGnostic(nb.PathParameterSubSchema); err != nil {
  827. return false, err
  828. } else if !nok {
  829. ok = false
  830. }
  831. if err := k.SimpleSchema.FromGnostic(nb.PathParameterSubSchema); err != nil {
  832. return false, err
  833. }
  834. if err := k.CommonValidations.FromGnostic(nb.PathParameterSubSchema); err != nil {
  835. return false, err
  836. }
  837. if err := k.VendorExtensible.FromGnostic(nb.PathParameterSubSchema.GetVendorExtension()); err != nil {
  838. return false, err
  839. }
  840. return ok, nil
  841. default:
  842. return false, errors.New("unrecognized nonbody type for Parameter")
  843. }
  844. default:
  845. return false, errors.New("unrecognized type for Parameter")
  846. }
  847. }
  848. type GnosticCommonParamProps interface {
  849. GetName() string
  850. GetRequired() bool
  851. GetIn() string
  852. GetDescription() string
  853. }
  854. type GnosticCommonParamPropsBodyParameter interface {
  855. GetSchema() *openapi_v2.Schema
  856. }
  857. type GnosticCommonParamPropsFormData interface {
  858. GetAllowEmptyValue() bool
  859. }
  860. func (k *ParamProps) FromGnostic(g GnosticCommonParamProps) (ok bool, err error) {
  861. ok = true
  862. k.Description = g.GetDescription()
  863. k.In = g.GetIn()
  864. k.Name = g.GetName()
  865. k.Required = g.GetRequired()
  866. if formDataParameter, success := g.(GnosticCommonParamPropsFormData); success {
  867. k.AllowEmptyValue = formDataParameter.GetAllowEmptyValue()
  868. }
  869. if bodyParameter, success := g.(GnosticCommonParamPropsBodyParameter); success {
  870. if bodyParameter.GetSchema() != nil {
  871. k.Schema = &Schema{}
  872. if nok, err := k.Schema.FromGnostic(bodyParameter.GetSchema()); err != nil {
  873. return false, err
  874. } else if !nok {
  875. ok = false
  876. }
  877. }
  878. }
  879. return ok, nil
  880. }
  881. // PB types use a different structure than we do for "refable". For PB, there is
  882. // a wrappign oneof type that could be a ref or the type
  883. func (k *Parameter) FromGnosticParametersItem(g *openapi_v2.ParametersItem) (ok bool, err error) {
  884. if g == nil {
  885. return true, nil
  886. }
  887. ok = true
  888. if ref := g.GetJsonReference(); ref != nil {
  889. k.Description = ref.Description
  890. if err := k.Refable.FromGnostic(ref.XRef); err != nil {
  891. return false, err
  892. }
  893. } else if nok, err := k.FromGnostic(g.GetParameter()); err != nil {
  894. return false, err
  895. } else if !nok {
  896. ok = false
  897. }
  898. return ok, nil
  899. }
  900. // Schema
  901. func (k *Schema) FromGnostic(g *openapi_v2.Schema) (ok bool, err error) {
  902. if g == nil {
  903. return true, nil
  904. }
  905. ok = true
  906. if err := k.VendorExtensible.FromGnostic(g.VendorExtension); err != nil {
  907. return false, err
  908. }
  909. // SwaggerSchemaProps
  910. k.Discriminator = g.Discriminator
  911. k.ReadOnly = g.ReadOnly
  912. k.Description = g.Description
  913. if g.ExternalDocs != nil {
  914. k.ExternalDocs = &ExternalDocumentation{}
  915. if nok, err := k.ExternalDocs.FromGnostic(g.ExternalDocs); err != nil {
  916. return false, err
  917. } else if !nok {
  918. ok = false
  919. }
  920. }
  921. if g.Example != nil {
  922. if err := g.Example.ToRawInfo().Decode(&k.Example); err != nil {
  923. return false, err
  924. }
  925. }
  926. // SchemaProps
  927. if err := k.Ref.FromGnostic(g.XRef); err != nil {
  928. return false, err
  929. }
  930. k.Type = g.Type.GetValue()
  931. k.Format = g.GetFormat()
  932. k.Title = g.GetTitle()
  933. // These below fields are not available in gnostic types, so will never
  934. // be populated. This means roundtrips which make use of these
  935. // (non-official, kube-only) fields will lose information.
  936. //
  937. // Schema.ID is not available in official spec
  938. // Schema.$schema
  939. // Schema.Nullable - in openapiv3, not v2
  940. // Schema.AnyOf - in openapiv3, not v2
  941. // Schema.OneOf - in openapiv3, not v2
  942. // Schema.Not - in openapiv3, not v2
  943. // Schema.PatternProperties - in openapiv3, not v2
  944. // Schema.Dependencies - in openapiv3, not v2
  945. // Schema.AdditionalItems
  946. // Schema.Definitions - not part of spec
  947. // Schema.ExtraProps - gnostic parser rejects any keys it does not recognize
  948. if g.GetDefault() != nil {
  949. if err := g.GetDefault().ToRawInfo().Decode(&k.Default); err != nil {
  950. return false, err
  951. }
  952. }
  953. // These conditionals (!= 0) follow gnostic's logic for ToRawInfo
  954. // The keys in gnostic source are only included if nonzero.
  955. if g.Maximum != 0.0 {
  956. k.Maximum = &g.Maximum
  957. }
  958. if g.Minimum != 0.0 {
  959. k.Minimum = &g.Minimum
  960. }
  961. k.ExclusiveMaximum = g.ExclusiveMaximum
  962. k.ExclusiveMinimum = g.ExclusiveMinimum
  963. if g.MaxLength != 0 {
  964. k.MaxLength = &g.MaxLength
  965. }
  966. if g.MinLength != 0 {
  967. k.MinLength = &g.MinLength
  968. }
  969. k.Pattern = g.GetPattern()
  970. if g.MaxItems != 0 {
  971. k.MaxItems = &g.MaxItems
  972. }
  973. if g.MinItems != 0 {
  974. k.MinItems = &g.MinItems
  975. }
  976. k.UniqueItems = g.UniqueItems
  977. if g.MultipleOf != 0 {
  978. k.MultipleOf = &g.MultipleOf
  979. }
  980. for _, v := range g.GetEnum() {
  981. if v == nil {
  982. continue
  983. }
  984. var convert interface{}
  985. if err := v.ToRawInfo().Decode(&convert); err != nil {
  986. return false, err
  987. }
  988. k.Enum = append(k.Enum, convert)
  989. }
  990. if g.MaxProperties != 0 {
  991. k.MaxProperties = &g.MaxProperties
  992. }
  993. if g.MinProperties != 0 {
  994. k.MinProperties = &g.MinProperties
  995. }
  996. k.Required = g.Required
  997. if g.GetItems() != nil {
  998. k.Items = &SchemaOrArray{}
  999. for _, v := range g.Items.GetSchema() {
  1000. if v == nil {
  1001. continue
  1002. }
  1003. schema := Schema{}
  1004. if nok, err := schema.FromGnostic(v); err != nil {
  1005. return false, err
  1006. } else if !nok {
  1007. ok = false
  1008. }
  1009. k.Items.Schemas = append(k.Items.Schemas, schema)
  1010. }
  1011. if len(k.Items.Schemas) == 1 {
  1012. k.Items.Schema = &k.Items.Schemas[0]
  1013. k.Items.Schemas = nil
  1014. }
  1015. }
  1016. for i, v := range g.GetAllOf() {
  1017. if v == nil {
  1018. continue
  1019. }
  1020. k.AllOf = append(k.AllOf, Schema{})
  1021. if nok, err := k.AllOf[i].FromGnostic(v); err != nil {
  1022. return false, err
  1023. } else if !nok {
  1024. ok = false
  1025. }
  1026. }
  1027. if g.Properties != nil {
  1028. k.Properties = make(map[string]Schema)
  1029. for _, namedSchema := range g.Properties.AdditionalProperties {
  1030. if namedSchema == nil {
  1031. continue
  1032. }
  1033. val := &Schema{}
  1034. if nok, err := val.FromGnostic(namedSchema.Value); err != nil {
  1035. return false, err
  1036. } else if !nok {
  1037. ok = false
  1038. }
  1039. k.Properties[namedSchema.Name] = *val
  1040. }
  1041. }
  1042. if g.AdditionalProperties != nil {
  1043. k.AdditionalProperties = &SchemaOrBool{}
  1044. if g.AdditionalProperties.GetSchema() == nil {
  1045. k.AdditionalProperties.Allows = g.AdditionalProperties.GetBoolean()
  1046. } else {
  1047. k.AdditionalProperties.Schema = &Schema{}
  1048. k.AdditionalProperties.Allows = true
  1049. if nok, err := k.AdditionalProperties.Schema.FromGnostic(g.AdditionalProperties.GetSchema()); err != nil {
  1050. return false, err
  1051. } else if !nok {
  1052. ok = false
  1053. }
  1054. }
  1055. }
  1056. return ok, nil
  1057. }
  1058. func (k *Schema) FromGnosticSchemaItem(g *openapi_v2.SchemaItem) (ok bool, err error) {
  1059. if g == nil {
  1060. return true, nil
  1061. }
  1062. ok = true
  1063. switch p := g.Oneof.(type) {
  1064. case *openapi_v2.SchemaItem_FileSchema:
  1065. fileSchema := p.FileSchema
  1066. if err := k.VendorExtensible.FromGnostic(fileSchema.VendorExtension); err != nil {
  1067. return false, err
  1068. }
  1069. k.Format = fileSchema.Format
  1070. k.Title = fileSchema.Title
  1071. k.Description = fileSchema.Description
  1072. k.Required = fileSchema.Required
  1073. k.Type = []string{fileSchema.Type}
  1074. k.ReadOnly = fileSchema.ReadOnly
  1075. if fileSchema.ExternalDocs != nil {
  1076. k.ExternalDocs = &ExternalDocumentation{}
  1077. if nok, err := k.ExternalDocs.FromGnostic(fileSchema.ExternalDocs); err != nil {
  1078. return false, err
  1079. } else if !nok {
  1080. ok = false
  1081. }
  1082. }
  1083. if fileSchema.Example != nil {
  1084. if err := fileSchema.Example.ToRawInfo().Decode(&k.Example); err != nil {
  1085. return false, err
  1086. }
  1087. }
  1088. if fileSchema.Default != nil {
  1089. if err := fileSchema.Default.ToRawInfo().Decode(&k.Default); err != nil {
  1090. return false, err
  1091. }
  1092. }
  1093. case *openapi_v2.SchemaItem_Schema:
  1094. schema := p.Schema
  1095. if nok, err := k.FromGnostic(schema); err != nil {
  1096. return false, err
  1097. } else if !nok {
  1098. ok = false
  1099. }
  1100. default:
  1101. return false, errors.New("unrecognized type for SchemaItem")
  1102. }
  1103. return ok, nil
  1104. }
  1105. // SecurityDefinitions
  1106. func (k SecurityDefinitions) FromGnostic(g *openapi_v2.SecurityDefinitions) error {
  1107. for _, v := range g.GetAdditionalProperties() {
  1108. if v == nil {
  1109. continue
  1110. }
  1111. secScheme := &SecurityScheme{}
  1112. if err := secScheme.FromGnostic(v.Value); err != nil {
  1113. return err
  1114. }
  1115. k[v.Name] = secScheme
  1116. }
  1117. return nil
  1118. }
  1119. type GnosticCommonSecurityDefinition interface {
  1120. GetType() string
  1121. GetDescription() string
  1122. }
  1123. func (k *SecuritySchemeProps) FromGnostic(g GnosticCommonSecurityDefinition) error {
  1124. k.Type = g.GetType()
  1125. k.Description = g.GetDescription()
  1126. if hasName, success := g.(interface{ GetName() string }); success {
  1127. k.Name = hasName.GetName()
  1128. }
  1129. if hasIn, success := g.(interface{ GetIn() string }); success {
  1130. k.In = hasIn.GetIn()
  1131. }
  1132. if hasFlow, success := g.(interface{ GetFlow() string }); success {
  1133. k.Flow = hasFlow.GetFlow()
  1134. }
  1135. if hasAuthURL, success := g.(interface{ GetAuthorizationUrl() string }); success {
  1136. k.AuthorizationURL = hasAuthURL.GetAuthorizationUrl()
  1137. }
  1138. if hasTokenURL, success := g.(interface{ GetTokenUrl() string }); success {
  1139. k.TokenURL = hasTokenURL.GetTokenUrl()
  1140. }
  1141. if hasScopes, success := g.(interface {
  1142. GetScopes() *openapi_v2.Oauth2Scopes
  1143. }); success {
  1144. scopes := hasScopes.GetScopes()
  1145. if scopes != nil {
  1146. k.Scopes = make(map[string]string, len(scopes.AdditionalProperties))
  1147. for _, v := range scopes.AdditionalProperties {
  1148. if v == nil {
  1149. continue
  1150. }
  1151. k.Scopes[v.Name] = v.Value
  1152. }
  1153. }
  1154. }
  1155. return nil
  1156. }
  1157. func (k *SecurityScheme) FromGnostic(g *openapi_v2.SecurityDefinitionsItem) error {
  1158. if g == nil {
  1159. return nil
  1160. }
  1161. switch s := g.Oneof.(type) {
  1162. case *openapi_v2.SecurityDefinitionsItem_ApiKeySecurity:
  1163. if err := k.SecuritySchemeProps.FromGnostic(s.ApiKeySecurity); err != nil {
  1164. return err
  1165. }
  1166. if err := k.VendorExtensible.FromGnostic(s.ApiKeySecurity.VendorExtension); err != nil {
  1167. return err
  1168. }
  1169. return nil
  1170. case *openapi_v2.SecurityDefinitionsItem_BasicAuthenticationSecurity:
  1171. if err := k.SecuritySchemeProps.FromGnostic(s.BasicAuthenticationSecurity); err != nil {
  1172. return err
  1173. }
  1174. if err := k.VendorExtensible.FromGnostic(s.BasicAuthenticationSecurity.VendorExtension); err != nil {
  1175. return err
  1176. }
  1177. return nil
  1178. case *openapi_v2.SecurityDefinitionsItem_Oauth2AccessCodeSecurity:
  1179. if err := k.SecuritySchemeProps.FromGnostic(s.Oauth2AccessCodeSecurity); err != nil {
  1180. return err
  1181. }
  1182. if err := k.VendorExtensible.FromGnostic(s.Oauth2AccessCodeSecurity.VendorExtension); err != nil {
  1183. return err
  1184. }
  1185. return nil
  1186. case *openapi_v2.SecurityDefinitionsItem_Oauth2ApplicationSecurity:
  1187. if err := k.SecuritySchemeProps.FromGnostic(s.Oauth2ApplicationSecurity); err != nil {
  1188. return err
  1189. }
  1190. if err := k.VendorExtensible.FromGnostic(s.Oauth2ApplicationSecurity.VendorExtension); err != nil {
  1191. return err
  1192. }
  1193. return nil
  1194. case *openapi_v2.SecurityDefinitionsItem_Oauth2ImplicitSecurity:
  1195. if err := k.SecuritySchemeProps.FromGnostic(s.Oauth2ImplicitSecurity); err != nil {
  1196. return err
  1197. }
  1198. if err := k.VendorExtensible.FromGnostic(s.Oauth2ImplicitSecurity.VendorExtension); err != nil {
  1199. return err
  1200. }
  1201. return nil
  1202. case *openapi_v2.SecurityDefinitionsItem_Oauth2PasswordSecurity:
  1203. if err := k.SecuritySchemeProps.FromGnostic(s.Oauth2PasswordSecurity); err != nil {
  1204. return err
  1205. }
  1206. if err := k.VendorExtensible.FromGnostic(s.Oauth2PasswordSecurity.VendorExtension); err != nil {
  1207. return err
  1208. }
  1209. return nil
  1210. default:
  1211. return errors.New("unrecognized SecurityDefinitionsItem")
  1212. }
  1213. }
  1214. // Tag
  1215. func (k *Tag) FromGnostic(g *openapi_v2.Tag) (ok bool, err error) {
  1216. if g == nil {
  1217. return true, nil
  1218. }
  1219. ok = true
  1220. if nok, err := k.TagProps.FromGnostic(g); err != nil {
  1221. return false, err
  1222. } else if !nok {
  1223. ok = false
  1224. }
  1225. if err := k.VendorExtensible.FromGnostic(g.VendorExtension); err != nil {
  1226. return false, err
  1227. }
  1228. return ok, nil
  1229. }
  1230. func (k *TagProps) FromGnostic(g *openapi_v2.Tag) (ok bool, err error) {
  1231. if g == nil {
  1232. return true, nil
  1233. }
  1234. ok = true
  1235. k.Description = g.Description
  1236. k.Name = g.Name
  1237. if g.ExternalDocs != nil {
  1238. k.ExternalDocs = &ExternalDocumentation{}
  1239. if nok, err := k.ExternalDocs.FromGnostic(g.ExternalDocs); err != nil {
  1240. return false, err
  1241. } else if !nok {
  1242. ok = false
  1243. }
  1244. }
  1245. return ok, nil
  1246. }
  1247. // ExternalDocumentation
  1248. func (k *ExternalDocumentation) FromGnostic(g *openapi_v2.ExternalDocs) (ok bool, err error) {
  1249. if g == nil {
  1250. return true, nil
  1251. }
  1252. ok = true
  1253. k.Description = g.Description
  1254. k.URL = g.Url
  1255. // data loss! g.VendorExtension
  1256. if len(g.VendorExtension) != 0 {
  1257. ok = false
  1258. }
  1259. return ok, nil
  1260. }