k8s.io/kube-openapi@v0.0.0-20240228011516-70dd3763d340/pkg/validation/spec/gnostic.go (about)

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