diff --git a/vendor.conf b/vendor.conf index eac243c0..55cfe29c 100644 --- a/vendor.conf +++ b/vendor.conf @@ -5,4 +5,4 @@ k8s.io/kubernetes v1.10.5 bitbucket.org/ww/goautoneg a547fc61f48d567d5b4ec6f8aee5573d8efce11d https://github.com/rancher/goautoneg.git golang.org/x/sync fd80eb99c8f653c847d294a001bdf2a3a6f768f5 -github.com/rancher/norman 0953e9e976f1038bb3e93e81d164a69d6fbe9873 +github.com/rancher/norman 12c3f92bed31fe8f49f699aabecdc79725b08bb6 diff --git a/vendor/github.com/rancher/norman/clientbase/common.go b/vendor/github.com/rancher/norman/clientbase/common.go index f3bb83df..2a1331fc 100644 --- a/vendor/github.com/rancher/norman/clientbase/common.go +++ b/vendor/github.com/rancher/norman/clientbase/common.go @@ -34,6 +34,7 @@ type APIBaseClientInterface interface { GetLink(resource types.Resource, link string, respObject interface{}) error Create(schemaType string, createObj interface{}, respObject interface{}) error Update(schemaType string, existing *types.Resource, updates interface{}, respObject interface{}) error + Replace(schemaType string, existing *types.Resource, updates interface{}, respObject interface{}) error ByID(schemaType string, id string, respObject interface{}) error Delete(existing *types.Resource) error Reload(existing *types.Resource, output interface{}) error @@ -53,6 +54,7 @@ type ClientOpts struct { TokenKey string Timeout time.Duration HTTPClient *http.Client + WSDialer *websocket.Dialer CACerts string Insecure bool } @@ -274,6 +276,10 @@ func NewAPIClient(opts *ClientOpts) (APIBaseClient, error) { Types: result.Types, } + if result.Opts.WSDialer != nil { + result.Ops.Dialer = result.Opts.WSDialer + } + ht, ok := client.Transport.(*http.Transport) if ok { result.Ops.Dialer.TLSClientConfig = ht.TLSClientConfig @@ -298,6 +304,10 @@ func (a *APIBaseClient) Websocket(url string, headers map[string][]string) (*web httpHeaders.Add("Authorization", a.Opts.getAuthHeader()) } + if Debug { + fmt.Println("WS " + url) + } + return a.Ops.Dialer.Dial(url, http.Header(httpHeaders)) } @@ -326,6 +336,10 @@ func (a *APIBaseClient) Update(schemaType string, existing *types.Resource, upda return a.Ops.DoUpdate(schemaType, existing, updates, respObject) } +func (a *APIBaseClient) Replace(schemaType string, existing *types.Resource, updates interface{}, respObject interface{}) error { + return a.Ops.DoReplace(schemaType, existing, updates, respObject) +} + func (a *APIBaseClient) ByID(schemaType string, id string, respObject interface{}) error { return a.Ops.DoByID(schemaType, id, respObject) } diff --git a/vendor/github.com/rancher/norman/condition/condition.go b/vendor/github.com/rancher/norman/condition/condition.go index f633a7a5..809af3a2 100644 --- a/vendor/github.com/rancher/norman/condition/condition.go +++ b/vendor/github.com/rancher/norman/condition/condition.go @@ -2,6 +2,7 @@ package condition import ( "reflect" + "regexp" "time" "github.com/pkg/errors" @@ -12,6 +13,8 @@ import ( type Cond string +var temfileRegexp = regexp.MustCompile("/tmp/[-_a-zA-Z0-9]+") + func (c Cond) True(obj runtime.Object) { setStatus(obj, string(c), "True") } @@ -133,9 +136,14 @@ func (c Cond) do(obj runtime.Object, f func() (runtime.Object, error)) (runtime. // This is to prevent non stop flapping of states and update if status == c.GetStatus(obj) && - reason == c.GetReason(obj) && - message == c.GetMessage(obj) { - c.LastUpdated(obj, ts) + reason == c.GetReason(obj) { + if message != c.GetMessage(obj) { + replaced := temfileRegexp.ReplaceAllString(c.GetMessage(obj), "file_path_redacted") + c.Message(obj, replaced) + } + if message == c.GetMessage(obj) { + c.LastUpdated(obj, ts) + } } return obj, err diff --git a/vendor/github.com/rancher/norman/controller/generic_controller.go b/vendor/github.com/rancher/norman/controller/generic_controller.go index 076dab9b..60fd3a10 100644 --- a/vendor/github.com/rancher/norman/controller/generic_controller.go +++ b/vendor/github.com/rancher/norman/controller/generic_controller.go @@ -3,6 +3,7 @@ package controller import ( "context" "fmt" + "os" "strings" "sync" "time" @@ -22,10 +23,19 @@ import ( "k8s.io/client-go/util/workqueue" ) +const MetricsEnv = "NORMAN_QUEUE_METRICS" + var ( resyncPeriod = 2 * time.Hour ) +// Override the metrics providers +func init() { + if os.Getenv(MetricsEnv) != "true" { + DisableAllControllerMetrics() + } +} + type HandlerFunc func(key string) error type GenericController interface { diff --git a/vendor/github.com/rancher/norman/controller/noop_metrics.go b/vendor/github.com/rancher/norman/controller/noop_metrics.go new file mode 100644 index 00000000..93ef91a5 --- /dev/null +++ b/vendor/github.com/rancher/norman/controller/noop_metrics.go @@ -0,0 +1,71 @@ +package controller + +import ( + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/workqueue" +) + +type noopMetric struct{} + +func (noopMetric) Inc() {} +func (noopMetric) Dec() {} +func (noopMetric) Observe(float64) {} +func (noopMetric) Set(float64) {} + +type noopWorkqueueMetricsProvider struct{} + +func (noopWorkqueueMetricsProvider) NewDepthMetric(name string) workqueue.GaugeMetric { + return noopMetric{} +} + +func (noopWorkqueueMetricsProvider) NewAddsMetric(name string) workqueue.CounterMetric { + return noopMetric{} +} + +func (noopWorkqueueMetricsProvider) NewLatencyMetric(name string) workqueue.SummaryMetric { + return noopMetric{} +} + +func (noopWorkqueueMetricsProvider) NewWorkDurationMetric(name string) workqueue.SummaryMetric { + return noopMetric{} +} + +func (noopWorkqueueMetricsProvider) NewRetriesMetric(name string) workqueue.CounterMetric { + return noopMetric{} +} + +type noopCacheMetricsProvider struct{} + +func (noopCacheMetricsProvider) NewListsMetric(name string) cache.CounterMetric { return noopMetric{} } +func (noopCacheMetricsProvider) NewListDurationMetric(name string) cache.SummaryMetric { + return noopMetric{} +} +func (noopCacheMetricsProvider) NewItemsInListMetric(name string) cache.SummaryMetric { + return noopMetric{} +} +func (noopCacheMetricsProvider) NewWatchesMetric(name string) cache.CounterMetric { return noopMetric{} } +func (noopCacheMetricsProvider) NewShortWatchesMetric(name string) cache.CounterMetric { + return noopMetric{} +} +func (noopCacheMetricsProvider) NewWatchDurationMetric(name string) cache.SummaryMetric { + return noopMetric{} +} +func (noopCacheMetricsProvider) NewItemsInWatchMetric(name string) cache.SummaryMetric { + return noopMetric{} +} +func (noopCacheMetricsProvider) NewLastResourceVersionMetric(name string) cache.GaugeMetric { + return noopMetric{} +} + +func DisableAllControllerMetrics() { + DisableControllerReflectorMetrics() + DisableControllerWorkqueuMetrics() +} + +func DisableControllerWorkqueuMetrics() { + workqueue.SetProvider(noopWorkqueueMetricsProvider{}) +} + +func DisableControllerReflectorMetrics() { + cache.SetReflectorMetricsProvider(noopCacheMetricsProvider{}) +} diff --git a/vendor/github.com/rancher/norman/generator/controller_template.go b/vendor/github.com/rancher/norman/generator/controller_template.go index 11482507..2f0d6a62 100644 --- a/vendor/github.com/rancher/norman/generator/controller_template.go +++ b/vendor/github.com/rancher/norman/generator/controller_template.go @@ -194,13 +194,6 @@ func (s *{{.schema.ID}}Client) ObjectClient() *objectclient.ObjectClient { } func (s *{{.schema.ID}}Client) Create(o *{{.prefix}}{{.schema.CodeName}}) (*{{.prefix}}{{.schema.CodeName}}, error) { - {{- if (or (eq .schema.ID "role") (eq .schema.ID "roleBinding") (eq .schema.ID "clusterRole") (eq .schema.ID "clusterRoleBinding"))}} - if o.Labels == nil { - labels := make(map[string]string) - o.Labels = labels - } - o.Labels["creator.cattle.io/rancher-created"] = "true" - {{- end}} obj, err := s.objectClient.Create(o) return obj.(*{{.prefix}}{{.schema.CodeName}}), err } @@ -216,13 +209,6 @@ func (s *{{.schema.ID}}Client) GetNamespaced(namespace, name string, opts metav1 } func (s *{{.schema.ID}}Client) Update(o *{{.prefix}}{{.schema.CodeName}}) (*{{.prefix}}{{.schema.CodeName}}, error) { - {{- if (or (eq .schema.ID "role") (eq .schema.ID "roleBinding") (eq .schema.ID "clusterRole") (eq .schema.ID "clusterRoleBinding"))}} - if o.Labels == nil { - labels := make(map[string]string) - o.Labels = labels - } - o.Labels["creator.cattle.io/rancher-created"] = "true" - {{- end}} obj, err := s.objectClient.Update(o.Name, o) return obj.(*{{.prefix}}{{.schema.CodeName}}), err } diff --git a/vendor/github.com/rancher/norman/objectclient/object_client.go b/vendor/github.com/rancher/norman/objectclient/object_client.go index 70fa3594..58d4f386 100644 --- a/vendor/github.com/rancher/norman/objectclient/object_client.go +++ b/vendor/github.com/rancher/norman/objectclient/object_client.go @@ -2,6 +2,7 @@ package objectclient import ( "encoding/json" + "strings" "github.com/pkg/errors" "github.com/rancher/norman/restwatch" @@ -11,10 +12,13 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + json2 "k8s.io/apimachinery/pkg/runtime/serializer/json" + "k8s.io/apimachinery/pkg/runtime/serializer/streaming" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/dynamic" "k8s.io/client-go/rest" + restclientwatch "k8s.io/client-go/rest/watch" ) type ObjectFactory interface { @@ -221,11 +225,38 @@ func (p *ObjectClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { if err != nil { return nil, err } - return watch.NewStreamWatcher(&dynamicDecoder{ + + embeddedDecoder := &structuredDecoder{ factory: p.Factory, - dec: json.NewDecoder(r), - close: r.Close, - }), nil + } + streamDecoder := streaming.NewDecoder(json2.Framer.NewFrameReader(r), embeddedDecoder) + decoder := restclientwatch.NewDecoder(streamDecoder, embeddedDecoder) + return watch.NewStreamWatcher(decoder), nil +} + +type structuredDecoder struct { + factory ObjectFactory +} + +func (d *structuredDecoder) Decode(data []byte, defaults *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) { + if into == nil { + into = d.factory.Object() + } + + err := json.Unmarshal(data, &into) + if err != nil { + return nil, nil, err + } + + if _, ok := into.(*metav1.Status); !ok && strings.ToLower(into.GetObjectKind().GroupVersionKind().Kind) == "status" { + into = &metav1.Status{} + err := json.Unmarshal(data, into) + if err != nil { + return nil, nil, err + } + } + + return into, defaults, err } func (p *ObjectClient) DeleteCollection(deleteOptions *metav1.DeleteOptions, listOptions metav1.ListOptions) error { @@ -263,40 +294,3 @@ func (p *ObjectClient) Patch(name string, o runtime.Object, data []byte, subreso func (p *ObjectClient) ObjectFactory() ObjectFactory { return p.Factory } - -type dynamicDecoder struct { - factory ObjectFactory - dec *json.Decoder - close func() error -} - -func (d *dynamicDecoder) Close() { - d.close() -} - -func (d *dynamicDecoder) Decode() (action watch.EventType, object runtime.Object, err error) { - e := dynamicEvent{ - Object: holder{ - factory: d.factory, - }, - } - if err := d.dec.Decode(&e); err != nil { - return watch.Error, nil, err - } - return e.Type, e.Object.obj, nil -} - -type dynamicEvent struct { - Type watch.EventType - Object holder -} - -type holder struct { - factory ObjectFactory - obj runtime.Object -} - -func (h *holder) UnmarshalJSON(b []byte) error { - h.obj = h.factory.Object() - return json.Unmarshal(b, h.obj) -} diff --git a/vendor/github.com/rancher/norman/store/proxy/proxy_store.go b/vendor/github.com/rancher/norman/store/proxy/proxy_store.go index 7a004b89..c5b57ab1 100644 --- a/vendor/github.com/rancher/norman/store/proxy/proxy_store.go +++ b/vendor/github.com/rancher/norman/store/proxy/proxy_store.go @@ -382,6 +382,7 @@ func (s *Store) Update(apiContext *types.APIContext, schema *types.Schema, data if errors.IsConflict(err) { continue } + return result, err } return result, err @@ -395,7 +396,7 @@ func (s *Store) Delete(apiContext *types.APIContext, schema *types.Schema, id st namespace, name := splitID(id) - prop := metav1.DeletePropagationForeground + prop := metav1.DeletePropagationBackground req := s.common(namespace, k8sClient.Delete()). Body(&metav1.DeleteOptions{ PropagationPolicy: &prop, diff --git a/vendor/github.com/rancher/norman/types/convert/merge/merge.go b/vendor/github.com/rancher/norman/types/convert/merge/merge.go index afc1a865..b37c9d09 100644 --- a/vendor/github.com/rancher/norman/types/convert/merge/merge.go +++ b/vendor/github.com/rancher/norman/types/convert/merge/merge.go @@ -9,7 +9,7 @@ import ( ) func APIUpdateMerge(schema *types.Schema, schemas *types.Schemas, dest, src map[string]interface{}, replace bool) map[string]interface{} { - result := mergeMaps(schema, schemas, replace, dest, src) + result := mergeMaps("", nil, schema, schemas, replace, dest, src) if s, ok := dest["status"]; ok { result["status"] = s } @@ -73,42 +73,58 @@ func mergeMetadata(dest map[string]interface{}, src map[string]interface{}) map[ return result } -func merge(field string, schema *types.Schema, schemas *types.Schemas, replace bool, dest, src interface{}) interface{} { - if isMap(field, schema) { +func merge(field, fieldType string, parentSchema, schema *types.Schema, schemas *types.Schemas, replace bool, dest, src interface{}) interface{} { + if isMap(field, schema, schemas) { return src } sm, smOk := src.(map[string]interface{}) dm, dmOk := dest.(map[string]interface{}) if smOk && dmOk { - return mergeMaps(getSchema(field, schema, schemas), schemas, replace, dm, sm) + fieldType, fieldSchema := getSchema(field, fieldType, parentSchema, schema, schemas) + return mergeMaps(fieldType, schema, fieldSchema, schemas, replace, dm, sm) } return src } -func getSchema(field string, schema *types.Schema, schemas *types.Schemas) *types.Schema { +func getSchema(field, parentFieldType string, parentSchema, schema *types.Schema, schemas *types.Schemas) (string, *types.Schema) { if schema == nil { - return nil + if definition.IsMapType(parentFieldType) && parentSchema != nil { + subType := definition.SubType(parentFieldType) + s := schemas.Schema(&parentSchema.Version, subType) + if s != nil && s.InternalSchema != nil { + s = s.InternalSchema + } + return subType, s + } + return "", nil } - s := schemas.Schema(&schema.Version, schema.ResourceFields[field].Type) + fieldType := schema.ResourceFields[field].Type + s := schemas.Schema(&schema.Version, fieldType) if s != nil && s.InternalSchema != nil { - return s.InternalSchema + return fieldType, s.InternalSchema } - return s + return fieldType, s } -func isMap(field string, schema *types.Schema) bool { +func isMap(field string, schema *types.Schema, schemas *types.Schemas) bool { if schema == nil { return false } f := schema.ResourceFields[field] - return definition.IsMapType(f.Type) + mapType := definition.IsMapType(f.Type) + if !mapType { + return false + } + + subType := definition.SubType(f.Type) + return schemas.Schema(&schema.Version, subType) == nil } -func mergeMaps(schema *types.Schema, schemas *types.Schemas, replace bool, dest map[string]interface{}, src map[string]interface{}) map[string]interface{} { +func mergeMaps(fieldType string, parentSchema, schema *types.Schema, schemas *types.Schemas, replace bool, dest map[string]interface{}, src map[string]interface{}) map[string]interface{} { result := copyMapReplace(schema, dest, replace) for k, v := range src { - result[k] = merge(k, schema, schemas, replace, dest[k], v) + result[k] = merge(k, fieldType, parentSchema, schema, schemas, replace, dest[k], v) } return result } @@ -124,7 +140,7 @@ func copyMap(src map[string]interface{}) map[string]interface{} { func copyMapReplace(schema *types.Schema, src map[string]interface{}, replace bool) map[string]interface{} { result := map[string]interface{}{} for k, v := range src { - if replace { + if replace && schema != nil { f := schema.ResourceFields[k] if f.Update { continue diff --git a/vendor/github.com/rancher/norman/types/mapper.go b/vendor/github.com/rancher/norman/types/mapper.go index 397c1f31..04f1ae0b 100644 --- a/vendor/github.com/rancher/norman/types/mapper.go +++ b/vendor/github.com/rancher/norman/types/mapper.go @@ -82,18 +82,12 @@ func (t *typeMapper) FromInternal(data map[string]interface{}) { } } - // Attempt to set type so mappers are aware of it if _, ok := data["type"]; !ok && data != nil { data["type"] = t.typeName } Mappers(t.Mappers).FromInternal(data) - // Ensure if there is no type we set one - if _, ok := data["type"]; !ok && data != nil { - data["type"] = t.typeName - } - if data != nil && t.root { if _, ok := data["id"]; ok { if namespace != "" { @@ -110,6 +104,12 @@ func (t *typeMapper) FromInternal(data map[string]interface{}) { } } } + + if _, ok := data["type"]; !ok && data != nil { + if _, ok := data["id"]; ok { + data["type"] = t.typeName + } + } } func (t *typeMapper) ToInternal(data map[string]interface{}) error { diff --git a/vendor/github.com/rancher/norman/types/reflection.go b/vendor/github.com/rancher/norman/types/reflection.go index 540929d8..0db14725 100644 --- a/vendor/github.com/rancher/norman/types/reflection.go +++ b/vendor/github.com/rancher/norman/types/reflection.go @@ -299,7 +299,7 @@ func (s *Schemas) readFields(schema *Schema, t reflect.Type) error { if schemaField.Type == "" { inferedType, err := s.determineSchemaType(&schema.Version, fieldType) if err != nil { - return err + return fmt.Errorf("failed inspecting type %s, field %s: %v", t, fieldName, err) } schemaField.Type = inferedType } @@ -421,6 +421,13 @@ func getKeyValue(input string) (string, string) { return key, value } +func deRef(p reflect.Type) reflect.Type { + if p.Kind() == reflect.Ptr { + return p.Elem() + } + return p +} + func (s *Schemas) determineSchemaType(version *APIVersion, t reflect.Type) (string, error) { switch t.Kind() { case reflect.Uint8: @@ -431,18 +438,20 @@ func (s *Schemas) determineSchemaType(version *APIVersion, t reflect.Type) (stri fallthrough case reflect.Int32: fallthrough + case reflect.Uint32: + fallthrough case reflect.Int64: return "int", nil case reflect.Interface: return "json", nil case reflect.Map: - subType, err := s.determineSchemaType(version, t.Elem()) + subType, err := s.determineSchemaType(version, deRef(t.Elem())) if err != nil { return "", err } return fmt.Sprintf("map[%s]", subType), nil case reflect.Slice: - subType, err := s.determineSchemaType(version, t.Elem()) + subType, err := s.determineSchemaType(version, deRef(t.Elem())) if err != nil { return "", err } diff --git a/vendor/github.com/rancher/norman/types/schemas.go b/vendor/github.com/rancher/norman/types/schemas.go index 2a45d7d9..f724c997 100644 --- a/vendor/github.com/rancher/norman/types/schemas.go +++ b/vendor/github.com/rancher/norman/types/schemas.go @@ -86,9 +86,6 @@ func (s *Schemas) doRemoveSchema(schema Schema) *Schemas { } func (s *Schemas) removeReferences(schema *Schema) { - fullType := convert.ToFullReference(schema.Version.Path, schema.ID) - delete(s.references, fullType) - for name, values := range s.references { changed := false var modified []BackReference