diff --git a/vendor.conf b/vendor.conf index fee9552a..73b07b1e 100644 --- a/vendor.conf +++ b/vendor.conf @@ -3,5 +3,5 @@ github.com/rancher/types k8s.io/kubernetes v1.8.3 transitive=true,staging=true bitbucket.org/ww/goautoneg a547fc61f48d567d5b4ec6f8aee5573d8efce11d https://github.com/rancher/goautoneg.git -github.com/rancher/norman 2550f12a9a3084d0b0d76e6c770196b093aff0f5 +github.com/rancher/norman a212c8c192b7438fd0504acba339028477a1fcd6 golang.org/x/sync fd80eb99c8f653c847d294a001bdf2a3a6f768f5 diff --git a/vendor/github.com/rancher/norman/clientbase/object_client.go b/vendor/github.com/rancher/norman/clientbase/object_client.go index e9e91373..bb1653a5 100644 --- a/vendor/github.com/rancher/norman/clientbase/object_client.go +++ b/vendor/github.com/rancher/norman/clientbase/object_client.go @@ -9,6 +9,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/dynamic" "k8s.io/client-go/rest" @@ -208,6 +209,27 @@ func (p *ObjectClient) DeleteCollection(deleteOptions *metav1.DeleteOptions, lis Error() } +func (p *ObjectClient) Patch(name string, o runtime.Object, data []byte, subresources ...string) (runtime.Object, error) { + ns := p.ns + if obj, ok := o.(metav1.Object); ok && obj.GetNamespace() != "" { + ns = obj.GetNamespace() + } + result := p.Factory.Object() + if len(name) == 0 { + return result, errors.New("object missing name") + } + err := p.restClient.Patch(types.StrategicMergePatchType). + Prefix(p.getAPIPrefix(), p.gvk.Group, p.gvk.Version). + NamespaceIfScoped(ns, p.resource.Namespaced). + Resource(p.resource.Name). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return result, err +} + type dynamicDecoder struct { factory ObjectFactory dec *json.Decoder diff --git a/vendor/github.com/rancher/norman/generator/client_template.go b/vendor/github.com/rancher/norman/generator/client_template.go index 89d95526..b7c673a8 100644 --- a/vendor/github.com/rancher/norman/generator/client_template.go +++ b/vendor/github.com/rancher/norman/generator/client_template.go @@ -10,7 +10,7 @@ type Client struct { clientbase.APIBaseClient {{range .schemas}} - {{- if . | hasGet }}{{.ID | capitalize}} {{.ID | capitalize}}Operations + {{- if . | hasGet }}{{.CodeName}} {{.CodeName}}Operations {{end}}{{end}}} func NewClient(opts *clientbase.ClientOpts) (*Client, error) { @@ -24,7 +24,7 @@ func NewClient(opts *clientbase.ClientOpts) (*Client, error) { } {{range .schemas}} - {{- if . | hasGet }}client.{{.ID | capitalize}} = new{{.ID | capitalize}}Client(client) + {{- if . | hasGet }}client.{{.CodeName}} = new{{.CodeName}}Client(client) {{end}}{{end}} return client, nil } diff --git a/vendor/github.com/rancher/norman/generator/controller_template.go b/vendor/github.com/rancher/norman/generator/controller_template.go index 47e52a61..1655bee2 100644 --- a/vendor/github.com/rancher/norman/generator/controller_template.go +++ b/vendor/github.com/rancher/norman/generator/controller_template.go @@ -198,6 +198,12 @@ func (s *{{.schema.ID}}Client) Watch(opts metav1.ListOptions) (watch.Interface, return s.objectClient.Watch(opts) } +// Patch applies the patch and returns the patched deployment. +func (s *{{.schema.ID}}Client) Patch(o *{{.prefix}}{{.schema.CodeName}}, data []byte, subresources ...string) (*{{.prefix}}{{.schema.CodeName}}, error) { + obj, err := s.objectClient.Patch(o.Name, o, data, subresources...) + return obj.(*{{.prefix}}{{.schema.CodeName}}), err +} + func (s *{{.schema.ID}}Client) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { return s.objectClient.DeleteCollection(deleteOpts, listOpts) } diff --git a/vendor/github.com/rancher/norman/generator/generator.go b/vendor/github.com/rancher/norman/generator/generator.go index d663b59d..ab259d13 100644 --- a/vendor/github.com/rancher/norman/generator/generator.go +++ b/vendor/github.com/rancher/norman/generator/generator.go @@ -52,6 +52,8 @@ func getTypeString(nullable bool, typeName string, schema *types.Schema, schemas name := "" switch typeName { + case "base64": + return "string" case "json": return "interface{}" case "boolean": diff --git a/vendor/github.com/rancher/norman/types/mapper.go b/vendor/github.com/rancher/norman/types/mapper.go index b7ad2c65..7baf6d8c 100644 --- a/vendor/github.com/rancher/norman/types/mapper.go +++ b/vendor/github.com/rancher/norman/types/mapper.go @@ -37,6 +37,7 @@ func (m Mappers) ModifySchema(schema *Schema, schemas *Schemas) error { type typeMapper struct { Mappers []Mapper + root bool typeName string subSchemas map[string]*Schema subArraySchemas map[string]*Schema @@ -64,10 +65,11 @@ func (t *typeMapper) FromInternal(data map[string]interface{}) { Mappers(t.Mappers).FromInternal(data) - if data != nil { - if _, ok := data["type"]; !ok { - data["type"] = t.typeName - } + if _, ok := data["type"]; !ok && data != nil { + data["type"] = t.typeName + } + + if data != nil && t.root { name, _ := data["name"].(string) namespace, _ := data["namespaceId"].(string) diff --git a/vendor/github.com/rancher/norman/types/mapper/access.go b/vendor/github.com/rancher/norman/types/mapper/access.go index 14043c58..21cace8a 100644 --- a/vendor/github.com/rancher/norman/types/mapper/access.go +++ b/vendor/github.com/rancher/norman/types/mapper/access.go @@ -18,7 +18,7 @@ func (e Access) ToInternal(data map[string]interface{}) { func (e Access) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { for name, access := range e.Fields { - if err := validateField(name, schema); err != nil { + if err := ValidateField(name, schema); err != nil { return err } diff --git a/vendor/github.com/rancher/norman/types/mapper/annotation_field.go b/vendor/github.com/rancher/norman/types/mapper/annotation_field.go index 94d68010..9bbf924c 100644 --- a/vendor/github.com/rancher/norman/types/mapper/annotation_field.go +++ b/vendor/github.com/rancher/norman/types/mapper/annotation_field.go @@ -9,8 +9,9 @@ import ( ) type AnnotationField struct { - Field string - Object bool + Field string + Object bool + IgnoreDefinition bool } func (e AnnotationField) FromInternal(data map[string]interface{}) { @@ -41,5 +42,8 @@ func (e AnnotationField) ToInternal(data map[string]interface{}) { } func (e AnnotationField) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { - return validateField(e.Field, schema) + if e.IgnoreDefinition { + return nil + } + return ValidateField(e.Field, schema) } diff --git a/vendor/github.com/rancher/norman/types/mapper/base64.go b/vendor/github.com/rancher/norman/types/mapper/base64.go new file mode 100644 index 00000000..bc0ceb4d --- /dev/null +++ b/vendor/github.com/rancher/norman/types/mapper/base64.go @@ -0,0 +1,61 @@ +package mapper + +import ( + "encoding/base64" + "strings" + + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" +) + +type Base64 struct { + Field string + IgnoreDefinition bool + Separator string +} + +func (m Base64) FromInternal(data map[string]interface{}) { + if v, ok := values.RemoveValue(data, strings.Split(m.Field, m.getSep())...); ok { + str := convert.ToString(v) + if str == "" { + return + } + + newData, err := base64.StdEncoding.DecodeString(str) + if err != nil { + log.Errorf("failed to base64 decode data") + } + + values.PutValue(data, string(newData), strings.Split(m.Field, m.getSep())...) + } +} + +func (m Base64) ToInternal(data map[string]interface{}) { + if v, ok := values.RemoveValue(data, strings.Split(m.Field, m.getSep())...); ok { + str := convert.ToString(v) + if str == "" { + return + } + + newData := base64.StdEncoding.EncodeToString([]byte(str)) + values.PutValue(data, newData, strings.Split(m.Field, m.getSep())...) + } +} + +func (m Base64) ModifySchema(s *types.Schema, schemas *types.Schemas) error { + if !m.IgnoreDefinition { + if err := ValidateField(m.Field, s); err != nil { + return err + } + } + + return nil +} + +func (m Base64) getSep() string { + if m.Separator == "" { + return "/" + } + return m.Separator +} diff --git a/vendor/github.com/rancher/norman/types/mapper/check.go b/vendor/github.com/rancher/norman/types/mapper/check.go index 30e7cefa..b31bbc07 100644 --- a/vendor/github.com/rancher/norman/types/mapper/check.go +++ b/vendor/github.com/rancher/norman/types/mapper/check.go @@ -6,7 +6,7 @@ import ( "github.com/rancher/norman/types" ) -func validateField(field string, schema *types.Schema) error { +func ValidateField(field string, schema *types.Schema) error { if _, ok := schema.ResourceFields[field]; !ok { return fmt.Errorf("field %s missing on schema %s", field, schema.ID) } diff --git a/vendor/github.com/rancher/norman/types/mapper/condition.go b/vendor/github.com/rancher/norman/types/mapper/condition.go new file mode 100644 index 00000000..bcd6d5dd --- /dev/null +++ b/vendor/github.com/rancher/norman/types/mapper/condition.go @@ -0,0 +1,27 @@ +package mapper + +import ( + "github.com/rancher/norman/types" +) + +type Condition struct { + Field string + Value interface{} + Mapper types.Mapper +} + +func (m Condition) FromInternal(data map[string]interface{}) { + if data[m.Field] == m.Value { + m.Mapper.FromInternal(data) + } +} + +func (m Condition) ToInternal(data map[string]interface{}) { + if data[m.Field] == m.Value { + m.Mapper.ToInternal(data) + } +} + +func (m Condition) ModifySchema(s *types.Schema, schemas *types.Schemas) error { + return m.Mapper.ModifySchema(s, schemas) +} diff --git a/vendor/github.com/rancher/norman/types/mapper/embed.go b/vendor/github.com/rancher/norman/types/mapper/embed.go index 94e7b9c7..86415f1a 100644 --- a/vendor/github.com/rancher/norman/types/mapper/embed.go +++ b/vendor/github.com/rancher/norman/types/mapper/embed.go @@ -43,7 +43,7 @@ func (e *Embed) ToInternal(data map[string]interface{}) { } func (e *Embed) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { - err := validateField(e.Field, schema) + err := ValidateField(e.Field, schema) if err != nil { if e.Optional { return nil diff --git a/vendor/github.com/rancher/norman/types/mapper/enum.go b/vendor/github.com/rancher/norman/types/mapper/enum.go index 96d2e69f..29b1cdb8 100644 --- a/vendor/github.com/rancher/norman/types/mapper/enum.go +++ b/vendor/github.com/rancher/norman/types/mapper/enum.go @@ -44,5 +44,5 @@ func (e Enum) ToInternal(data map[string]interface{}) { } func (e Enum) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { - return validateField(e.Field, schema) + return ValidateField(e.Field, schema) } diff --git a/vendor/github.com/rancher/norman/types/mapper/json_encode.go b/vendor/github.com/rancher/norman/types/mapper/json_encode.go new file mode 100644 index 00000000..af728366 --- /dev/null +++ b/vendor/github.com/rancher/norman/types/mapper/json_encode.go @@ -0,0 +1,51 @@ +package mapper + +import ( + "strings" + + "encoding/json" + + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" +) + +type JSONEncode struct { + Field string + IgnoreDefinition bool + Separator string +} + +func (m JSONEncode) FromInternal(data map[string]interface{}) { + if v, ok := values.RemoveValue(data, strings.Split(m.Field, m.getSep())...); ok { + obj := map[string]interface{}{} + if err := json.Unmarshal([]byte(convert.ToString(v)), &obj); err == nil { + values.PutValue(data, obj, strings.Split(m.Field, m.getSep())...) + } else { + log.Errorf("Failed to unmarshal json field: %v", err) + } + } +} + +func (m JSONEncode) ToInternal(data map[string]interface{}) { + if v, ok := values.RemoveValue(data, strings.Split(m.Field, m.getSep())...); ok && v != nil { + if bytes, err := json.Marshal(v); err == nil { + values.PutValue(data, string(bytes), strings.Split(m.Field, m.getSep())...) + } + } +} + +func (m JSONEncode) getSep() string { + if m.Separator == "" { + return "/" + } + return m.Separator +} + +func (m JSONEncode) ModifySchema(s *types.Schema, schemas *types.Schemas) error { + if m.IgnoreDefinition { + return nil + } + + return ValidateField(m.Field, s) +} diff --git a/vendor/github.com/rancher/norman/types/mapper/label_field.go b/vendor/github.com/rancher/norman/types/mapper/label_field.go index 1ffe5458..da8852a1 100644 --- a/vendor/github.com/rancher/norman/types/mapper/label_field.go +++ b/vendor/github.com/rancher/norman/types/mapper/label_field.go @@ -24,5 +24,5 @@ func (e LabelField) ToInternal(data map[string]interface{}) { } func (e LabelField) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { - return validateField(e.Field, schema) + return ValidateField(e.Field, schema) } diff --git a/vendor/github.com/rancher/norman/types/mapper/log.go b/vendor/github.com/rancher/norman/types/mapper/log.go new file mode 100644 index 00000000..0743c403 --- /dev/null +++ b/vendor/github.com/rancher/norman/types/mapper/log.go @@ -0,0 +1,7 @@ +package mapper + +import "github.com/sirupsen/logrus" + +var ( + log = logrus.WithField("component", "norman/mapper") +) diff --git a/vendor/github.com/rancher/norman/types/mapper/metadata.go b/vendor/github.com/rancher/norman/types/mapper/metadata.go index 2e06845d..c857047c 100644 --- a/vendor/github.com/rancher/norman/types/mapper/metadata.go +++ b/vendor/github.com/rancher/norman/types/mapper/metadata.go @@ -7,7 +7,9 @@ import ( func NewMetadataMapper() types.Mapper { return types.Mappers{ Drop{"generateName"}, - Move{From: "selfLink", To: "resourcePath"}, + //Move{From: "selfLink", To: "resourcePath"}, + Drop{"selfLink"}, + //Drop{"ownerReferences"}, Move{From: "uid", To: "uuid"}, Drop{"resourceVersion"}, Drop{"generation"}, diff --git a/vendor/github.com/rancher/norman/types/mapper/read_only.go b/vendor/github.com/rancher/norman/types/mapper/read_only.go index 71054496..311e933b 100644 --- a/vendor/github.com/rancher/norman/types/mapper/read_only.go +++ b/vendor/github.com/rancher/norman/types/mapper/read_only.go @@ -25,7 +25,7 @@ func (r ReadOnly) ModifySchema(schema *types.Schema, schemas *types.Schemas) err return nil } - if err := validateField(r.Field, schema); err != nil { + if err := ValidateField(r.Field, schema); err != nil { if r.Optional { return nil } diff --git a/vendor/github.com/rancher/norman/types/mapper/set_value.go b/vendor/github.com/rancher/norman/types/mapper/set_value.go index 58558693..81253c7e 100644 --- a/vendor/github.com/rancher/norman/types/mapper/set_value.go +++ b/vendor/github.com/rancher/norman/types/mapper/set_value.go @@ -10,40 +10,59 @@ import ( ) type SetValue struct { - From, To string - Value interface{} - IfEq interface{} + Field, To string + Value interface{} + IfEq interface{} + IgnoreDefinition bool } func (s SetValue) FromInternal(data map[string]interface{}) { - v, ok := values.GetValue(data, strings.Split(s.From, "/")...) + if s.IfEq == nil { + values.PutValue(data, s.Value, strings.Split(s.getTo(), "/")...) + return + } + + v, ok := values.GetValue(data, strings.Split(s.Field, "/")...) if !ok { return } if v == s.IfEq { - values.PutValue(data, s.Value, strings.Split(s.To, "/")...) + values.PutValue(data, s.Value, strings.Split(s.getTo(), "/")...) } } +func (s SetValue) getTo() string { + if s.To == "" { + return s.Field + } + return s.To +} + func (s SetValue) ToInternal(data map[string]interface{}) { - v, ok := values.GetValue(data, strings.Split(s.To, "/")...) + v, ok := values.GetValue(data, strings.Split(s.getTo(), "/")...) if !ok { return } - if v == s.Value { - values.PutValue(data, s.IfEq, strings.Split(s.From, "/")...) + if s.IfEq == nil { + values.RemoveValue(data, strings.Split(s.Field, "/")...) + } else if v == s.Value { + values.PutValue(data, s.IfEq, strings.Split(s.Field, "/")...) } } func (s SetValue) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { - _, _, _, ok, err := getField(schema, schemas, s.To) + if s.IgnoreDefinition { + return nil + } + + _, _, _, ok, err := getField(schema, schemas, s.getTo()) if err != nil { return err } if !ok { - return fmt.Errorf("failed to find defined field for %s on schemas %s", s.To, schema.ID) + return fmt.Errorf("failed to find defined field for %s on schemas %s", s.getTo(), schema.ID) } return nil diff --git a/vendor/github.com/rancher/norman/types/mapper/slice_to_map.go b/vendor/github.com/rancher/norman/types/mapper/slice_to_map.go index 64886563..78c47cd3 100644 --- a/vendor/github.com/rancher/norman/types/mapper/slice_to_map.go +++ b/vendor/github.com/rancher/norman/types/mapper/slice_to_map.go @@ -47,7 +47,7 @@ func (s SliceToMap) ToInternal(data map[string]interface{}) { } func (s SliceToMap) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { - err := validateField(s.Field, schema) + err := ValidateField(s.Field, schema) if err != nil { return err } diff --git a/vendor/github.com/rancher/norman/types/mapper/untyped_move.go b/vendor/github.com/rancher/norman/types/mapper/untyped_move.go new file mode 100644 index 00000000..4b1a4910 --- /dev/null +++ b/vendor/github.com/rancher/norman/types/mapper/untyped_move.go @@ -0,0 +1,36 @@ +package mapper + +import ( + "strings" + + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/values" +) + +type UntypedMove struct { + From, To string + Separator string +} + +func (m UntypedMove) FromInternal(data map[string]interface{}) { + if v, ok := values.RemoveValue(data, strings.Split(m.From, m.getSep())...); ok { + values.PutValue(data, v, strings.Split(m.To, m.getSep())...) + } +} + +func (m UntypedMove) ToInternal(data map[string]interface{}) { + if v, ok := values.RemoveValue(data, strings.Split(m.To, m.getSep())...); ok { + values.PutValue(data, v, strings.Split(m.From, m.getSep())...) + } +} + +func (m UntypedMove) getSep() string { + if m.Separator == "" { + return "/" + } + return m.Separator +} + +func (m UntypedMove) ModifySchema(s *types.Schema, schemas *types.Schemas) error { + return nil +} diff --git a/vendor/github.com/rancher/norman/types/reflection.go b/vendor/github.com/rancher/norman/types/reflection.go index 060f9803..5b0cb51b 100644 --- a/vendor/github.com/rancher/norman/types/reflection.go +++ b/vendor/github.com/rancher/norman/types/reflection.go @@ -26,13 +26,25 @@ var ( } ) +func (s *Schemas) TypeName(name string, obj interface{}) *Schemas { + s.typeNames[reflect.TypeOf(obj)] = name + return s +} + +func (s *Schemas) getTypeName(t reflect.Type) string { + if name, ok := s.typeNames[t]; ok { + return name + } + return convert.LowerTitle(t.Name()) +} + func (s *Schemas) AddMapperForType(version *APIVersion, obj interface{}, mapper ...Mapper) *Schemas { if len(mapper) == 0 { return s } t := reflect.TypeOf(obj) - typeName := convert.LowerTitle(t.Name()) + typeName := s.getTypeName(t) if len(mapper) == 1 { return s.AddMapper(version, typeName, mapper[0]) } @@ -111,7 +123,7 @@ func (s *Schemas) setupFilters(schema *Schema) { } func (s *Schemas) MustCustomizeType(version *APIVersion, obj interface{}, f func(*Schema)) *Schemas { - name := convert.LowerTitle(reflect.TypeOf(obj).Name()) + name := s.getTypeName(reflect.TypeOf(obj)) schema := s.Schema(version, name) if schema == nil { panic("Failed to find schema " + name) @@ -127,7 +139,7 @@ func (s *Schemas) MustCustomizeType(version *APIVersion, obj interface{}, f func } func (s *Schemas) importType(version *APIVersion, t reflect.Type, overrides ...reflect.Type) (*Schema, error) { - typeName := convert.LowerTitle(t.Name()) + typeName := s.getTypeName(t) existing := s.Schema(version, typeName) if existing != nil { @@ -167,6 +179,7 @@ func (s *Schemas) importType(version *APIVersion, t reflect.Type, overrides ...r mapper := &typeMapper{ Mappers: mappers, + root: schema.CanList(), } if err := mapper.ModifySchema(schema, s); err != nil { @@ -376,6 +389,8 @@ func getKeyValue(input string) (string, string) { func (s *Schemas) determineSchemaType(version *APIVersion, t reflect.Type) (string, error) { switch t.Kind() { + case reflect.Uint8: + return "byte", nil case reflect.Bool: return "boolean", nil case reflect.Int: @@ -397,6 +412,9 @@ func (s *Schemas) determineSchemaType(version *APIVersion, t reflect.Type) (stri if err != nil { return "", err } + if subType == "byte" { + return "base64", nil + } return fmt.Sprintf("array[%s]", subType), nil case reflect.String: return "string", nil diff --git a/vendor/github.com/rancher/norman/types/schemas.go b/vendor/github.com/rancher/norman/types/schemas.go index d9747e2a..0d939a2d 100644 --- a/vendor/github.com/rancher/norman/types/schemas.go +++ b/vendor/github.com/rancher/norman/types/schemas.go @@ -3,8 +3,8 @@ package types import ( "bytes" "fmt" + "reflect" "strings" - "sync" "github.com/rancher/norman/name" @@ -29,6 +29,7 @@ type BackReference struct { type Schemas struct { sync.Mutex + typeNames map[reflect.Type]string schemasByPath map[string]map[string]*Schema schemasBySubContext map[string]*Schema mappers map[string]map[string][]Mapper @@ -44,6 +45,7 @@ type Schemas struct { func NewSchemas() *Schemas { return &Schemas{ + typeNames: map[reflect.Type]string{}, schemasByPath: map[string]map[string]*Schema{}, schemasBySubContext: map[string]*Schema{}, mappers: map[string]map[string][]Mapper{}, diff --git a/vendor/github.com/rancher/norman/types/server_types.go b/vendor/github.com/rancher/norman/types/server_types.go index 1ad12e98..a5071749 100644 --- a/vendor/github.com/rancher/norman/types/server_types.go +++ b/vendor/github.com/rancher/norman/types/server_types.go @@ -3,6 +3,7 @@ package types import ( "encoding/json" "net/http" + "net/url" ) type ValuesMap struct { @@ -79,6 +80,7 @@ type APIContext struct { Schema *Schema Schemas *Schemas Version *APIVersion + Query url.Values ResponseFormat string ReferenceValidator ReferenceValidator ResponseWriter ResponseWriter