Change:
Using kubectl create with a list no longer works. We get the output:
In kubernetes 1.0 with a List would create all items in the List.
Test data to duplicate the problem:
CC
FYI in case you run into this.
Another feature that needs a test.
the swagger spec may only include object definitions that are registered as API request/response types... since isn't actually submitted to the server (that I know of), that's probably why it didn't get included. Enabling validation by default () probably exposed the bug with a List not being able to validate
We need to make validation on List work. We should test multiple resources w/o List as well.
Naive question: Could we just call Schema() after Flatten() but before Do()?
Hmm. No, validation isn't actually called there.
Each input-source visitor (URLVisitor, FileVisitor, StreamVisitor) has its own call to ValidateSchema. We need to validate before decoding, but we don't unpack the list until after decoding.
We could do something similar to FlattenListVisitor in ValidateSchema: But that's pretty ugly.
Do you have time to take a look at what the most straightforward solution/workaround is for this? Longer-term we should maybe push this into the json decoder, as proposed here:
The simplest thing might be to add List to the swaggerapi models list… I was looking into that yesterday and got sidetracked
I thought about adding List, but it didn't look like the validator would recurse into the individual resource models, hence the need to special-case List.
Nobody is working on this at the moment, if you'd like to take a look.
OK, I will take a look.
If add List to the swaggerapi, I think it need to add a new api . If we post request to to handler the List, need to unpack the list in the server. Or just add an "empty" api only list the List kind ? I think that might be a little strange all above. Please correct me.
I recommended not adding List to the swagger. I don't think it would help. I think we need to detect the case of a List and extract the resources within, similar to FlattenListVisitor.
I agree. I think doing something similar to FlattenListVisitor in ValidateSchema maybe a little ugly. But it's straightforward.

Discussion:
"fmt" "reflect" "regexp" <ins> "strings" </ins> "github.com/emicklei/go-restful/swagger" "github.com/golang/glog"

return schema, nil } <ins> // validateList unpack a list and validate every item in the list. // It return nil if every item is ok. // Otherwise it return an error list contain errors of every item. func (s *SwaggerSchema) validateList(obj map[string]interface{}) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} items, exists := obj["items"] if !exists { return append(allErrs, fmt.Errorf("no items field in %#v", obj)) } itemList, ok := items.([]interface{}) if !ok { return append(allErrs, fmt.Errorf("items isn't a slice")) } for i, item := range itemList { fields, ok := item.(map[string]interface{}) if !ok { allErrs = append(allErrs, fmt.Errorf("items[%d] isn't a map[string]interface{}", i)) continue } groupVersion := fields["apiVersion"] if groupVersion == nil { allErrs = append(allErrs, fmt.Errorf("items[%d].apiVersion not set", i)) continue } itemVersion, ok := groupVersion.(string) if !ok { allErrs = append(allErrs, fmt.Errorf("items[%d].apiVersion isn't string type", i)) continue } if len(itemVersion) == 0 { allErrs = append(allErrs, fmt.Errorf("items[%d].apiVersion is empty", i)) } kind := fields["kind"] if kind == nil { allErrs = append(allErrs, fmt.Errorf("items[%d].kind not set", i)) continue } itemKind, ok := kind.(string) if !ok { allErrs = append(allErrs, fmt.Errorf("items[%d].kind isn't string type", i)) continue } if len(itemKind) == 0 { allErrs = append(allErrs, fmt.Errorf("items[%d].kind is empty", i)) } version := apiutil.GetVersion(itemVersion) errs := s.ValidateObject(item, "", version+"."+itemKind) if len(errs) >= 1 { allErrs = append(allErrs, errs...) } } return allErrs } </ins> func (s *SwaggerSchema) ValidateBytes(data []byte) error { var obj interface{} out, err := yaml.ToJSON(data)

if groupVersion == nil { return fmt.Errorf("apiVersion not set") } <ins> if _, ok := groupVersion.(string); !ok { return fmt.Errorf("apiVersion isn't string type") } </ins> kind := fields["kind"] if kind == nil { return fmt.Errorf("kind not set") } <ins> if _, ok := kind.(string); !ok { return fmt.Errorf("kind isn't string type") } if strings.HasSuffix(kind.(string), "List") { return errors.NewAggregate(s.validateList(fields)) } </ins> version := apiutil.GetVersion(groupVersion.(string)) allErrs := s.ValidateObject(obj, "", version+"."+kind.(string)) if len(allErrs) == 1 {