diff --git a/vendor.conf b/vendor.conf index 0f0e9994..2166d4e1 100644 --- a/vendor.conf +++ b/vendor.conf @@ -5,4 +5,4 @@ k8s.io/kubernetes v1.8.3 bitbucket.org/ww/goautoneg a547fc61f48d567d5b4ec6f8aee5573d8efce11d https://github.com/rancher/goautoneg.git golang.org/x/sync fd80eb99c8f653c847d294a001bdf2a3a6f768f5 -github.com/rancher/norman ff60298f31f081b06d198815b4c178a578664f7d +github.com/rancher/norman 0611d5f7a126637abad8f0e5734cbc6562ed3922 diff --git a/vendor/github.com/rancher/norman/clientbase/client.go b/vendor/github.com/rancher/norman/clientbase/client.go deleted file mode 100644 index 69805cab..00000000 --- a/vendor/github.com/rancher/norman/clientbase/client.go +++ /dev/null @@ -1,19 +0,0 @@ -package clientbase - -import ( - "net/http" - - "github.com/rancher/norman/types" -) - -type APIBaseClient struct { - Ops *APIOperations - Opts *ClientOpts - Types map[string]types.Schema -} - -type APIOperations struct { - Opts *ClientOpts - Types map[string]types.Schema - Client *http.Client -} diff --git a/vendor/github.com/rancher/norman/clientbase/common.go b/vendor/github.com/rancher/norman/clientbase/common.go index 73dcb7a0..aa3e9662 100644 --- a/vendor/github.com/rancher/norman/clientbase/common.go +++ b/vendor/github.com/rancher/norman/clientbase/common.go @@ -28,6 +28,25 @@ var ( dialer = &websocket.Dialer{} ) +type APIBaseClientInterface interface { + Websocket(url string, headers map[string][]string) (*websocket.Conn, *http.Response, error) + List(schemaType string, opts *types.ListOpts, respObject interface{}) error + Post(url string, createObj interface{}, respObject interface{}) error + 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 + ByID(schemaType string, id string, respObject interface{}) error + Delete(existing *types.Resource) error + Reload(existing *types.Resource, output interface{}) error + Action(schemaType string, action string, existing *types.Resource, inputObject, respObject interface{}) error +} + +type APIBaseClient struct { + Ops *APIOperations + Opts *ClientOpts + Types map[string]types.Schema +} + type ClientOpts struct { URL string AccessKey string diff --git a/vendor/github.com/rancher/norman/clientbase/ops.go b/vendor/github.com/rancher/norman/clientbase/ops.go index ebeccb61..b96d1760 100644 --- a/vendor/github.com/rancher/norman/clientbase/ops.go +++ b/vendor/github.com/rancher/norman/clientbase/ops.go @@ -12,6 +12,12 @@ import ( "github.com/rancher/norman/types" ) +type APIOperations struct { + Opts *ClientOpts + Types map[string]types.Schema + Client *http.Client +} + func (a *APIOperations) setupRequest(req *http.Request) { req.Header.Add("Authorization", a.Opts.getAuthHeader()) } diff --git a/vendor/github.com/rancher/norman/controller/cluster_check.go b/vendor/github.com/rancher/norman/controller/cluster_check.go index 6d5f2d58..a548f96c 100644 --- a/vendor/github.com/rancher/norman/controller/cluster_check.go +++ b/vendor/github.com/rancher/norman/controller/cluster_check.go @@ -30,6 +30,15 @@ func ObjectInCluster(cluster string, obj interface{}) bool { } } } + if clusterName == "" { + if a := getValue(obj, "Annotations"); a.IsValid() { + if c := a.MapIndex(reflect.ValueOf("field.cattle.io/projectId")); c.IsValid() { + if parts := strings.SplitN(c.String(), ":", 2); len(parts) == 2 { + clusterName = parts[0] + } + } + } + } return clusterName == cluster } diff --git a/vendor/github.com/rancher/norman/controller/generic_controller.go b/vendor/github.com/rancher/norman/controller/generic_controller.go index 37cead8e..b2d9ddfb 100644 --- a/vendor/github.com/rancher/norman/controller/generic_controller.go +++ b/vendor/github.com/rancher/norman/controller/generic_controller.go @@ -64,7 +64,7 @@ func NewGenericController(name string, genericClient Backend) GenericController ListFunc: genericClient.List, WatchFunc: genericClient.Watch, }, - genericClient.ObjectFactory().Object(), resyncPeriod, cache.Indexers{}) + genericClient.ObjectFactory().Object(), resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) rl := workqueue.NewMaxOfRateLimiter( workqueue.NewItemExponentialFailureRateLimiter(500*time.Millisecond, 1000*time.Second), diff --git a/vendor/github.com/rancher/norman/objectclient/object_client.go b/vendor/github.com/rancher/norman/objectclient/object_client.go index 80a565d9..70fa3594 100644 --- a/vendor/github.com/rancher/norman/objectclient/object_client.go +++ b/vendor/github.com/rancher/norman/objectclient/object_client.go @@ -103,6 +103,7 @@ func (p *ObjectClient) Create(o runtime.Object) (runtime.Object, error) { } } result := p.Factory.Object() + logrus.Debugf("REST CREATE %s/%s/%s/%s/%s", p.getAPIPrefix(), p.gvk.Group, p.gvk.Version, ns, p.resource.Name) err := p.restClient.Post(). Prefix(p.getAPIPrefix(), p.gvk.Group, p.gvk.Version). NamespaceIfScoped(ns, p.resource.Namespaced). @@ -126,6 +127,7 @@ func (p *ObjectClient) GetNamespaced(namespace, name string, opts metav1.GetOpti Name(name). Do(). Into(result) + logrus.Debugf("REST GET %s/%s/%s/%s/%s/%s", p.getAPIPrefix(), p.gvk.Group, p.gvk.Version, namespace, p.resource.Name, name) return result, err } @@ -140,6 +142,7 @@ func (p *ObjectClient) Get(name string, opts metav1.GetOptions) (runtime.Object, Name(name). Do(). Into(result) + logrus.Debugf("REST GET %s/%s/%s/%s/%s/%s", p.getAPIPrefix(), p.gvk.Group, p.gvk.Version, p.ns, p.resource.Name, name) return result, err } @@ -152,7 +155,7 @@ func (p *ObjectClient) Update(name string, o runtime.Object) (runtime.Object, er if len(name) == 0 { return result, errors.New("object missing name") } - logrus.Debugf("UPDATE %s/%s/%s/%s/%s/%s", p.getAPIPrefix(), p.gvk.Group, p.gvk.Version, ns, p.resource.Name, name) + logrus.Debugf("REST UPDATE %s/%s/%s/%s/%s/%s", p.getAPIPrefix(), p.gvk.Group, p.gvk.Version, ns, p.resource.Name, name) err := p.restClient.Put(). Prefix(p.getAPIPrefix(), p.gvk.Group, p.gvk.Version). NamespaceIfScoped(ns, p.resource.Namespaced). @@ -170,6 +173,7 @@ func (p *ObjectClient) DeleteNamespaced(namespace, name string, opts *metav1.Del if namespace != "" { req = req.Namespace(namespace) } + logrus.Debugf("REST DELETE %s/%s/%s/%s/%s/%s", p.getAPIPrefix(), p.gvk.Group, p.gvk.Version, namespace, p.resource.Name, name) return req.Resource(p.resource.Name). Name(name). Body(opts). @@ -178,6 +182,7 @@ func (p *ObjectClient) DeleteNamespaced(namespace, name string, opts *metav1.Del } func (p *ObjectClient) Delete(name string, opts *metav1.DeleteOptions) error { + logrus.Debugf("REST DELETE %s/%s/%s/%s/%s/%s", p.getAPIPrefix(), p.gvk.Group, p.gvk.Version, p.ns, p.resource.Name, name) return p.restClient.Delete(). Prefix(p.getAPIPrefix(), p.gvk.Group, p.gvk.Version). NamespaceIfScoped(p.ns, p.resource.Namespaced). @@ -190,6 +195,7 @@ func (p *ObjectClient) Delete(name string, opts *metav1.DeleteOptions) error { func (p *ObjectClient) List(opts metav1.ListOptions) (runtime.Object, error) { result := p.Factory.List() + logrus.Debugf("REST LIST %s/%s/%s/%s/%s", p.getAPIPrefix(), p.gvk.Group, p.gvk.Version, p.ns, p.resource.Name) return result, p.restClient.Get(). Prefix(p.getAPIPrefix(), p.gvk.Group, p.gvk.Version). NamespaceIfScoped(p.ns, p.resource.Namespaced). 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 be8388e2..6c245804 100644 --- a/vendor/github.com/rancher/norman/store/proxy/proxy_store.go +++ b/vendor/github.com/rancher/norman/store/proxy/proxy_store.go @@ -6,6 +6,7 @@ import ( "strings" "time" + "github.com/rancher/norman/httperror" "github.com/rancher/norman/restwatch" "github.com/rancher/norman/types" "github.com/rancher/norman/types/convert" @@ -117,7 +118,7 @@ func (p *Store) getUser(apiContext *types.APIContext) string { func (p *Store) doAuthed(apiContext *types.APIContext, request *rest.Request) rest.Result { start := time.Now() defer func() { - logrus.Debug("GET:", time.Now().Sub(start), p.resourcePlural) + logrus.Debug("GET: ", time.Now().Sub(start), p.resourcePlural) }() for _, header := range authHeaders { @@ -131,6 +132,18 @@ func (p *Store) k8sClient(apiContext *types.APIContext) (rest.Interface, error) } func (p *Store) ByID(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + splitted := strings.Split(strings.TrimSpace(id), ":") + validID := false + namespaced := schema.Scope == types.NamespaceScope + if namespaced { + validID = len(splitted) == 2 && len(strings.TrimSpace(splitted[0])) > 0 && len(strings.TrimSpace(splitted[1])) > 0 + } else { + validID = len(splitted) == 1 && len(strings.TrimSpace(splitted[0])) > 0 + } + if !validID { + return nil, httperror.NewAPIError(httperror.NotFound, "failed to find resource by id") + } + _, result, err := p.byID(apiContext, schema, id) return result, err } @@ -166,7 +179,7 @@ func (p *Store) List(apiContext *types.APIContext, schema *types.Schema, opt *ty resultList := &unstructured.UnstructuredList{} start := time.Now() err = req.Do().Into(resultList) - logrus.Debug("LIST:", time.Now().Sub(start), p.resourcePlural) + logrus.Debug("LIST: ", time.Now().Sub(start), p.resourcePlural) if err != nil { return nil, err } @@ -266,7 +279,7 @@ func (p *Store) Create(apiContext *types.APIContext, schema *types.Schema, data if name == "" { generated, _ := values.GetValueN(data, "metadata", "generateName").(string) if generated == "" { - values.PutValue(data, strings.ToLower(schema.ID+"-"), "metadata", "generateName") + values.PutValue(data, types.GenerateName(schema.ID), "metadata", "name") } } @@ -335,14 +348,14 @@ func (p *Store) Delete(apiContext *types.APIContext, schema *types.Schema, id st return nil, err } - namespace, id := splitID(id) + namespace, name := splitID(id) prop := metav1.DeletePropagationForeground req := p.common(namespace, k8sClient.Delete()). Body(&metav1.DeleteOptions{ PropagationPolicy: &prop, }). - Name(id) + Name(name) err = p.doAuthed(apiContext, req).Error() if err != nil { diff --git a/vendor/github.com/rancher/norman/types/id.go b/vendor/github.com/rancher/norman/types/id.go new file mode 100644 index 00000000..9c6618d1 --- /dev/null +++ b/vendor/github.com/rancher/norman/types/id.go @@ -0,0 +1,19 @@ +package types + +import ( + "fmt" + "regexp" + "strings" + + utilrand "k8s.io/apimachinery/pkg/util/rand" +) + +var ( + lowerChars = regexp.MustCompile("[a-z]+") +) + +func GenerateName(typeName string) string { + base := typeName[0:1] + lowerChars.ReplaceAllString(typeName[1:], "") + last := utilrand.String(5) + return fmt.Sprintf("%s-%s", strings.ToLower(base), last) +} diff --git a/vendor/github.com/rancher/norman/types/mapper/copy.go b/vendor/github.com/rancher/norman/types/mapper/copy.go new file mode 100644 index 00000000..805e0749 --- /dev/null +++ b/vendor/github.com/rancher/norman/types/mapper/copy.go @@ -0,0 +1,42 @@ +package mapper + +import ( + "fmt" + + "github.com/rancher/norman/types" +) + +type Copy struct { + From, To string +} + +func (c Copy) FromInternal(data map[string]interface{}) { + if data == nil { + return + } + v, ok := data[c.From] + if ok { + data[c.To] = v + } +} + +func (c Copy) ToInternal(data map[string]interface{}) { + if data == nil { + return + } + t, tok := data[c.To] + _, fok := data[c.From] + if tok && !fok { + data[c.From] = t + } +} + +func (c Copy) ModifySchema(s *types.Schema, schemas *types.Schemas) error { + f, ok := s.ResourceFields[c.From] + if !ok { + return fmt.Errorf("field %s missing on schema %s", c.From, s.ID) + } + + s.ResourceFields[c.To] = f + return nil +} diff --git a/vendor/github.com/rancher/norman/types/mapper/embed.go b/vendor/github.com/rancher/norman/types/mapper/embed.go index fd6ea08d..06d4f572 100644 --- a/vendor/github.com/rancher/norman/types/mapper/embed.go +++ b/vendor/github.com/rancher/norman/types/mapper/embed.go @@ -38,7 +38,9 @@ func (e *Embed) ToInternal(data map[string]interface{}) { delete(data, fieldName) } - + if len(sub) == 0 { + return + } data[e.Field] = sub } diff --git a/vendor/github.com/rancher/norman/types/reflection.go b/vendor/github.com/rancher/norman/types/reflection.go index dcb82592..fe240cac 100644 --- a/vendor/github.com/rancher/norman/types/reflection.go +++ b/vendor/github.com/rancher/norman/types/reflection.go @@ -95,6 +95,8 @@ func (s *Schemas) setupFilters(schema *Schema) { switch field.Type { case "enum": mods = []ModifierType{ModifierEQ, ModifierNE, ModifierIn, ModifierNotIn} + case "dnsLabel": + fallthrough case "string": mods = []ModifierType{ModifierEQ, ModifierNE, ModifierIn, ModifierNotIn} case "int": diff --git a/vendor/k8s.io/apimachinery/pkg/util/rand/BUILD b/vendor/k8s.io/apimachinery/pkg/util/rand/BUILD new file mode 100644 index 00000000..a92d241f --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/rand/BUILD @@ -0,0 +1,31 @@ +package(default_visibility = ["//visibility:public"]) + +load( + "@io_bazel_rules_go//go:def.bzl", + "go_library", + "go_test", +) + +go_test( + name = "go_default_test", + srcs = ["rand_test.go"], + library = ":go_default_library", +) + +go_library( + name = "go_default_library", + srcs = ["rand.go"], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], +) diff --git a/vendor/k8s.io/apimachinery/pkg/util/rand/rand.go b/vendor/k8s.io/apimachinery/pkg/util/rand/rand.go new file mode 100644 index 00000000..4c593b3c --- /dev/null +++ b/vendor/k8s.io/apimachinery/pkg/util/rand/rand.go @@ -0,0 +1,95 @@ +/* +Copyright 2015 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package rand provides utilities related to randomization. +package rand + +import ( + "math/rand" + "sync" + "time" +) + +var rng = struct { + sync.Mutex + rand *rand.Rand +}{ + rand: rand.New(rand.NewSource(time.Now().UTC().UnixNano())), +} + +// Intn generates an integer in range [0,max). +// By design this should panic if input is invalid, <= 0. +func Intn(max int) int { + rng.Lock() + defer rng.Unlock() + return rng.rand.Intn(max) +} + +// IntnRange generates an integer in range [min,max). +// By design this should panic if input is invalid, <= 0. +func IntnRange(min, max int) int { + rng.Lock() + defer rng.Unlock() + return rng.rand.Intn(max-min) + min +} + +// IntnRange generates an int64 integer in range [min,max). +// By design this should panic if input is invalid, <= 0. +func Int63nRange(min, max int64) int64 { + rng.Lock() + defer rng.Unlock() + return rng.rand.Int63n(max-min) + min +} + +// Seed seeds the rng with the provided seed. +func Seed(seed int64) { + rng.Lock() + defer rng.Unlock() + + rng.rand = rand.New(rand.NewSource(seed)) +} + +// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n) +// from the default Source. +func Perm(n int) []int { + rng.Lock() + defer rng.Unlock() + return rng.rand.Perm(n) +} + +// We omit vowels from the set of available characters to reduce the chances +// of "bad words" being formed. +var alphanums = []rune("bcdfghjklmnpqrstvwxz2456789") + +// String generates a random alphanumeric string, without vowels, which is n +// characters long. This will panic if n is less than zero. +func String(length int) string { + b := make([]rune, length) + for i := range b { + b[i] = alphanums[Intn(len(alphanums))] + } + return string(b) +} + +// SafeEncodeString encodes s using the same characters as rand.String. This reduces the chances of bad words and +// ensures that strings generated from hash functions appear consistent throughout the API. +func SafeEncodeString(s string) string { + r := make([]rune, len(s)) + for i, b := range []rune(s) { + r[i] = alphanums[(int(b) % len(alphanums))] + } + return string(r) +}