mirror of
https://github.com/kubernetes/client-go.git
synced 2025-06-27 07:28:14 +00:00
Merge pull request #68748 from p0lyn0mial/dynamic_lister_informer
adds dynamic lister Kubernetes-commit: 23baf579c8cfc7d69fefac17ecd271321b15fc54
This commit is contained in:
commit
bb17ab6ef1
102
Godeps/Godeps.json
generated
102
Godeps/Godeps.json
generated
@ -400,207 +400,207 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/api/apitesting",
|
"ImportPath": "k8s.io/apimachinery/pkg/api/apitesting",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/api/apitesting/fuzzer",
|
"ImportPath": "k8s.io/apimachinery/pkg/api/apitesting/fuzzer",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/api/apitesting/roundtrip",
|
"ImportPath": "k8s.io/apimachinery/pkg/api/apitesting/roundtrip",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/api/equality",
|
"ImportPath": "k8s.io/apimachinery/pkg/api/equality",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/api/errors",
|
"ImportPath": "k8s.io/apimachinery/pkg/api/errors",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/api/meta",
|
"ImportPath": "k8s.io/apimachinery/pkg/api/meta",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/api/resource",
|
"ImportPath": "k8s.io/apimachinery/pkg/api/resource",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/fuzzer",
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/fuzzer",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/internalversion",
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/internalversion",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured",
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1beta1",
|
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1beta1",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/conversion",
|
"ImportPath": "k8s.io/apimachinery/pkg/conversion",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams",
|
"ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/fields",
|
"ImportPath": "k8s.io/apimachinery/pkg/fields",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/labels",
|
"ImportPath": "k8s.io/apimachinery/pkg/labels",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime",
|
"ImportPath": "k8s.io/apimachinery/pkg/runtime",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/schema",
|
"ImportPath": "k8s.io/apimachinery/pkg/runtime/schema",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer",
|
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/json",
|
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/json",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/protobuf",
|
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/protobuf",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/recognizer",
|
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/recognizer",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/streaming",
|
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/streaming",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/versioning",
|
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/versioning",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/selection",
|
"ImportPath": "k8s.io/apimachinery/pkg/selection",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/types",
|
"ImportPath": "k8s.io/apimachinery/pkg/types",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/cache",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/cache",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/clock",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/clock",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/diff",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/diff",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/errors",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/errors",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/framer",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/framer",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/httpstream",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/httpstream",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/httpstream/spdy",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/httpstream/spdy",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/intstr",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/intstr",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/json",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/json",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/mergepatch",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/mergepatch",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/naming",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/naming",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/net",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/net",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/remotecommand",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/remotecommand",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/runtime",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/runtime",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/sets",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/sets",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/validation",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/validation",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/validation/field",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/validation/field",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/wait",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/wait",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/util/yaml",
|
"ImportPath": "k8s.io/apimachinery/pkg/util/yaml",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/version",
|
"ImportPath": "k8s.io/apimachinery/pkg/version",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/pkg/watch",
|
"ImportPath": "k8s.io/apimachinery/pkg/watch",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json",
|
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/netutil",
|
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/netutil",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
|
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
|
||||||
"Rev": "a191abe0b71e00ce4cde58af8002aa4c1a8bb068"
|
"Rev": "18b50c81aee7a3efd24f37d0510ea2e19411c69c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
|
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
|
||||||
|
40
dynamic/dynamiclister/interface.go
Normal file
40
dynamic/dynamiclister/interface.go
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 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 dynamiclister
|
||||||
|
|
||||||
|
import (
|
||||||
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Lister helps list resources.
|
||||||
|
type Lister interface {
|
||||||
|
// List lists all resources in the indexer.
|
||||||
|
List(selector labels.Selector) (ret []*unstructured.Unstructured, err error)
|
||||||
|
// Get retrieves a resource from the indexer with the given name
|
||||||
|
Get(name string) (*unstructured.Unstructured, error)
|
||||||
|
// Namespace returns an object that can list and get resources in a given namespace.
|
||||||
|
Namespace(namespace string) NamespaceLister
|
||||||
|
}
|
||||||
|
|
||||||
|
// NamespaceLister helps list and get resources.
|
||||||
|
type NamespaceLister interface {
|
||||||
|
// List lists all resources in the indexer for a given namespace.
|
||||||
|
List(selector labels.Selector) (ret []*unstructured.Unstructured, err error)
|
||||||
|
// Get retrieves a resource from the indexer for a given namespace and name.
|
||||||
|
Get(name string) (*unstructured.Unstructured, error)
|
||||||
|
}
|
91
dynamic/dynamiclister/lister.go
Normal file
91
dynamic/dynamiclister/lister.go
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 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 dynamiclister
|
||||||
|
|
||||||
|
import (
|
||||||
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/client-go/tools/cache"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ Lister = &dynamicLister{}
|
||||||
|
var _ NamespaceLister = &dynamicNamespaceLister{}
|
||||||
|
|
||||||
|
// dynamicLister implements the Lister interface.
|
||||||
|
type dynamicLister struct {
|
||||||
|
indexer cache.Indexer
|
||||||
|
gvr schema.GroupVersionResource
|
||||||
|
}
|
||||||
|
|
||||||
|
// New returns a new Lister.
|
||||||
|
func New(indexer cache.Indexer, gvr schema.GroupVersionResource) Lister {
|
||||||
|
return &dynamicLister{indexer: indexer, gvr: gvr}
|
||||||
|
}
|
||||||
|
|
||||||
|
// List lists all resources in the indexer.
|
||||||
|
func (l *dynamicLister) List(selector labels.Selector) (ret []*unstructured.Unstructured, err error) {
|
||||||
|
err = cache.ListAll(l.indexer, selector, func(m interface{}) {
|
||||||
|
ret = append(ret, m.(*unstructured.Unstructured))
|
||||||
|
})
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get retrieves a resource from the indexer with the given name
|
||||||
|
func (l *dynamicLister) Get(name string) (*unstructured.Unstructured, error) {
|
||||||
|
obj, exists, err := l.indexer.GetByKey(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
return nil, errors.NewNotFound(l.gvr.GroupResource(), name)
|
||||||
|
}
|
||||||
|
return obj.(*unstructured.Unstructured), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Namespace returns an object that can list and get resources from a given namespace.
|
||||||
|
func (l *dynamicLister) Namespace(namespace string) NamespaceLister {
|
||||||
|
return &dynamicNamespaceLister{indexer: l.indexer, namespace: namespace, gvr: l.gvr}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dynamicNamespaceLister implements the NamespaceLister interface.
|
||||||
|
type dynamicNamespaceLister struct {
|
||||||
|
indexer cache.Indexer
|
||||||
|
namespace string
|
||||||
|
gvr schema.GroupVersionResource
|
||||||
|
}
|
||||||
|
|
||||||
|
// List lists all resources in the indexer for a given namespace.
|
||||||
|
func (l *dynamicNamespaceLister) List(selector labels.Selector) (ret []*unstructured.Unstructured, err error) {
|
||||||
|
err = cache.ListAllByNamespace(l.indexer, l.namespace, selector, func(m interface{}) {
|
||||||
|
ret = append(ret, m.(*unstructured.Unstructured))
|
||||||
|
})
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get retrieves a resource from the indexer for a given namespace and name.
|
||||||
|
func (l *dynamicNamespaceLister) Get(name string) (*unstructured.Unstructured, error) {
|
||||||
|
obj, exists, err := l.indexer.GetByKey(l.namespace + "/" + name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
return nil, errors.NewNotFound(l.gvr.GroupResource(), name)
|
||||||
|
}
|
||||||
|
return obj.(*unstructured.Unstructured), nil
|
||||||
|
}
|
257
dynamic/dynamiclister/lister_test.go
Normal file
257
dynamic/dynamiclister/lister_test.go
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 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 dynamiclister_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/apimachinery/pkg/util/diff"
|
||||||
|
"k8s.io/client-go/dynamic/dynamiclister"
|
||||||
|
"k8s.io/client-go/tools/cache"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNamespaceGetMethod(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
existingObjects []runtime.Object
|
||||||
|
namespaceToSync string
|
||||||
|
gvrToSync schema.GroupVersionResource
|
||||||
|
objectToGet string
|
||||||
|
expectedObject *unstructured.Unstructured
|
||||||
|
expectError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "scenario 1: gets name-foo1 resource from the indexer from ns-foo namespace",
|
||||||
|
existingObjects: []runtime.Object{
|
||||||
|
newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"),
|
||||||
|
newUnstructured("group/version", "TheKind", "ns-foo", "name-foo1"),
|
||||||
|
newUnstructured("group/version", "TheKind", "ns-bar", "name-bar"),
|
||||||
|
},
|
||||||
|
namespaceToSync: "ns-foo",
|
||||||
|
gvrToSync: schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"},
|
||||||
|
objectToGet: "name-foo1",
|
||||||
|
expectedObject: newUnstructured("group/version", "TheKind", "ns-foo", "name-foo1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "scenario 2: gets name-foo-non-existing resource from the indexer from ns-foo namespace",
|
||||||
|
existingObjects: []runtime.Object{
|
||||||
|
newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"),
|
||||||
|
newUnstructured("group/version", "TheKind", "ns-foo", "name-foo1"),
|
||||||
|
newUnstructured("group/version", "TheKind", "ns-bar", "name-bar"),
|
||||||
|
},
|
||||||
|
namespaceToSync: "ns-foo",
|
||||||
|
gvrToSync: schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"},
|
||||||
|
objectToGet: "name-foo-non-existing",
|
||||||
|
expectError: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
// test data
|
||||||
|
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{})
|
||||||
|
for _, obj := range test.existingObjects {
|
||||||
|
err := indexer.Add(obj)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// act
|
||||||
|
target := dynamiclister.New(indexer, test.gvrToSync).Namespace(test.namespaceToSync)
|
||||||
|
actualObject, err := target.Get(test.objectToGet)
|
||||||
|
|
||||||
|
// validate
|
||||||
|
if test.expectError {
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("expected to get an error but non was returned")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(test.expectedObject, actualObject) {
|
||||||
|
t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", test.expectedObject, actualObject, diff.ObjectDiff(test.expectedObject, actualObject))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNamespaceListMethod(t *testing.T) {
|
||||||
|
// test data
|
||||||
|
objs := []runtime.Object{
|
||||||
|
newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"),
|
||||||
|
newUnstructured("group/version", "TheKind", "ns-foo", "name-foo1"),
|
||||||
|
newUnstructured("group/version", "TheKind", "ns-bar", "name-bar"),
|
||||||
|
}
|
||||||
|
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{})
|
||||||
|
for _, obj := range objs {
|
||||||
|
err := indexer.Add(obj)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expectedOutput := []*unstructured.Unstructured{
|
||||||
|
newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"),
|
||||||
|
newUnstructured("group/version", "TheKind", "ns-foo", "name-foo1"),
|
||||||
|
}
|
||||||
|
namespaceToList := "ns-foo"
|
||||||
|
|
||||||
|
// act
|
||||||
|
target := dynamiclister.New(indexer, schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"}).Namespace(namespaceToList)
|
||||||
|
actualOutput, err := target.List(labels.Everything())
|
||||||
|
|
||||||
|
// validate
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assertListOrDie(expectedOutput, actualOutput, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListerGetMethod(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
existingObjects []runtime.Object
|
||||||
|
namespaceToSync string
|
||||||
|
gvrToSync schema.GroupVersionResource
|
||||||
|
objectToGet string
|
||||||
|
expectedObject *unstructured.Unstructured
|
||||||
|
expectError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "scenario 1: gets name-foo1 resource from the indexer",
|
||||||
|
existingObjects: []runtime.Object{
|
||||||
|
newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"),
|
||||||
|
newUnstructured("group/version", "TheKind", "", "name-foo1"),
|
||||||
|
newUnstructured("group/version", "TheKind", "ns-bar", "name-bar"),
|
||||||
|
},
|
||||||
|
namespaceToSync: "",
|
||||||
|
gvrToSync: schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"},
|
||||||
|
objectToGet: "name-foo1",
|
||||||
|
expectedObject: newUnstructured("group/version", "TheKind", "", "name-foo1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "scenario 2: doesn't get name-foo resource from the indexer from ns-foo namespace",
|
||||||
|
existingObjects: []runtime.Object{
|
||||||
|
newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"),
|
||||||
|
newUnstructured("group/version", "TheKind", "ns-foo", "name-foo1"),
|
||||||
|
newUnstructured("group/version", "TheKind", "ns-bar", "name-bar"),
|
||||||
|
},
|
||||||
|
namespaceToSync: "ns-foo",
|
||||||
|
gvrToSync: schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"},
|
||||||
|
objectToGet: "name-foo",
|
||||||
|
expectError: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
// test data
|
||||||
|
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{})
|
||||||
|
for _, obj := range test.existingObjects {
|
||||||
|
err := indexer.Add(obj)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// act
|
||||||
|
target := dynamiclister.New(indexer, test.gvrToSync)
|
||||||
|
actualObject, err := target.Get(test.objectToGet)
|
||||||
|
|
||||||
|
// validate
|
||||||
|
if test.expectError {
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("expected to get an error but non was returned")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(test.expectedObject, actualObject) {
|
||||||
|
t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", test.expectedObject, actualObject, diff.ObjectDiff(test.expectedObject, actualObject))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListerListMethod(t *testing.T) {
|
||||||
|
// test data
|
||||||
|
objs := []runtime.Object{
|
||||||
|
newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"),
|
||||||
|
newUnstructured("group/version", "TheKind", "ns-foo", "name-bar"),
|
||||||
|
}
|
||||||
|
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{})
|
||||||
|
for _, obj := range objs {
|
||||||
|
err := indexer.Add(obj)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expectedOutput := []*unstructured.Unstructured{
|
||||||
|
newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"),
|
||||||
|
newUnstructured("group/version", "TheKind", "ns-foo", "name-bar"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// act
|
||||||
|
target := dynamiclister.New(indexer, schema.GroupVersionResource{Group: "group", Version: "version", Resource: "TheKinds"})
|
||||||
|
actualOutput, err := target.List(labels.Everything())
|
||||||
|
|
||||||
|
// validate
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
assertListOrDie(expectedOutput, actualOutput, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newUnstructured(apiVersion, kind, namespace, name string) *unstructured.Unstructured {
|
||||||
|
return &unstructured.Unstructured{
|
||||||
|
Object: map[string]interface{}{
|
||||||
|
"apiVersion": apiVersion,
|
||||||
|
"kind": kind,
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"namespace": namespace,
|
||||||
|
"name": name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertListOrDie(expected, actual []*unstructured.Unstructured, t *testing.T) {
|
||||||
|
if len(actual) != len(expected) {
|
||||||
|
t.Fatalf("unexpected number of items returned, expected = %d, actual = %d", len(expected), len(actual))
|
||||||
|
}
|
||||||
|
for _, expectedObject := range expected {
|
||||||
|
found := false
|
||||||
|
for _, actualObject := range actual {
|
||||||
|
if actualObject.GetName() == expectedObject.GetName() {
|
||||||
|
if !reflect.DeepEqual(expectedObject, actualObject) {
|
||||||
|
t.Fatalf("unexpected object has been returned expected = %v actual = %v, diff = %v", expectedObject, actualObject, diff.ObjectDiff(expectedObject, actualObject))
|
||||||
|
}
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
t.Fatalf("the resource with the name = %s was not found in the returned output", expectedObject.GetName())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user