mirror of
https://github.com/kubernetes/client-go.git
synced 2026-05-16 12:22:43 +00:00
Compare commits
75 Commits
v9.0.0
...
release-7.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36368dede2 | ||
|
|
648b80a212 | ||
|
|
16a8a034ed | ||
|
|
751eb6abb5 | ||
|
|
745ca83003 | ||
|
|
56edb76093 | ||
|
|
a9a2ba84e6 | ||
|
|
fa6525815c | ||
|
|
a312bfe35c | ||
|
|
805e310466 | ||
|
|
26a26f55b2 | ||
|
|
0be17c78bf | ||
|
|
1d79704297 | ||
|
|
33f2870a2b | ||
|
|
27ca8df003 | ||
|
|
262ea94a59 | ||
|
|
345769d958 | ||
|
|
ac76ac5060 | ||
|
|
989be4278f | ||
|
|
74d8cc8c8f | ||
|
|
fd2b358bbe | ||
|
|
694c2d5e5f | ||
|
|
d7928f5b56 | ||
|
|
d5472ab191 | ||
|
|
2fce0bafad | ||
|
|
5d7eb0287c | ||
|
|
123c6c6318 | ||
|
|
d6de2be5f2 | ||
|
|
0caa5e78a2 | ||
|
|
f29a60b40a | ||
|
|
b16d5cf21d | ||
|
|
ce807c7acd | ||
|
|
a359b79224 | ||
|
|
06ac755d8d | ||
|
|
ab10f7aa22 | ||
|
|
78a1c5c6e7 | ||
|
|
a3e9cfc0b8 | ||
|
|
77e73af6e6 | ||
|
|
1bc18ec750 | ||
|
|
87e5a5fc06 | ||
|
|
c6810f466e | ||
|
|
d8f55ede17 | ||
|
|
d1f2f22256 | ||
|
|
ef0fd623c9 | ||
|
|
00b7839442 | ||
|
|
f29d72208b | ||
|
|
52a78f7b0f | ||
|
|
5d7928c541 | ||
|
|
25505bfbc7 | ||
|
|
f8c68b19c4 | ||
|
|
c4b9f086d0 | ||
|
|
89fa90e86a | ||
|
|
da7a6fee9d | ||
|
|
0ff29eaf80 | ||
|
|
7e3e837ff5 | ||
|
|
ad9b46a1e9 | ||
|
|
f9840ecc2e | ||
|
|
abbedebe40 | ||
|
|
7c9b0dc097 | ||
|
|
50a0fcce59 | ||
|
|
16d72c3ed9 | ||
|
|
6e2b4fff22 | ||
|
|
afa6acd011 | ||
|
|
cfa927c19f | ||
|
|
e5261fe39c | ||
|
|
5c4221286f | ||
|
|
d22e08fbc4 | ||
|
|
a3bffe5d33 | ||
|
|
5f742c0476 | ||
|
|
05d8c8911c | ||
|
|
f48569b364 | ||
|
|
ed49bb3574 | ||
|
|
dea0758d47 | ||
|
|
1a16aa9e1a | ||
|
|
5ab5f98777 |
5
.github/PULL_REQUEST_TEMPLATE.md
vendored
5
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,3 +1,2 @@
|
||||
Sorry, we do not accept changes directly against this repository, unless the
|
||||
change is to the `README.md` itself. Please see
|
||||
`CONTRIBUTING.md` for information on where and how to contribute instead.
|
||||
Sorry, we do not accept changes directly against this repository. Please see
|
||||
CONTRIBUTING.md for information on where and how to contribute instead.
|
||||
|
||||
@@ -3,6 +3,6 @@ language: go
|
||||
go_import_path: k8s.io/client-go
|
||||
|
||||
go:
|
||||
- 1.10.2
|
||||
- 1.8.1
|
||||
|
||||
script: go build ./...
|
||||
|
||||
285
CHANGELOG.md
285
CHANGELOG.md
@@ -1,293 +1,10 @@
|
||||
TODO: This document was manually maintained so might be incomplete. The
|
||||
automation effort is tracked in
|
||||
https://github.com/kubernetes/test-infra/issues/5843.
|
||||
https://github.com/kubernetes/client-go/issues/234.
|
||||
|
||||
Changes in `k8s.io/api` and `k8s.io/apimachinery` are mentioned here
|
||||
because `k8s.io/client-go` depends on them.
|
||||
|
||||
# v8.0.0
|
||||
|
||||
**Breaking Changes:**
|
||||
|
||||
* `KUBE_API_VERSIONS` has been removed.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/63165](https://github.com/kubernetes/kubernetes/pull/63165)
|
||||
|
||||
* The client-go/discovery `RESTMapper` has been moved to client-go/restmapper.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/63507](https://github.com/kubernetes/kubernetes/pull/63507)
|
||||
|
||||
* `CachedDiscoveryClient` has been moved from kubectl to client-go.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/63550](https://github.com/kubernetes/kubernetes/pull/63550)
|
||||
|
||||
* The `EventRecorder` interface is changed to include an `AnnotatedEventf` method, which can add annotations to an event.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/64213](https://github.com/kubernetes/kubernetes/pull/64213)
|
||||
|
||||
* [k8s.io/apimachinery] The deprecated `RepairMalformedUpdates` flag has been removed.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/61455](https://github.com/kubernetes/kubernetes/pull/61455)
|
||||
|
||||
**New Features:**
|
||||
|
||||
* A new easy-to-use dynamic client is added and the old dynamic client is now deprecated.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/62913](https://github.com/kubernetes/kubernetes/pull/62913)
|
||||
|
||||
* client-go and kubectl now detect and report an error on duplicated name for user, cluster and context, while loading the kubeconfig.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/60464](https://github.com/kubernetes/kubernetes/pull/60464)
|
||||
|
||||
* The informer code-generator now allows specifying a custom resync period for certain informer types and uses the default resync period if none is specified.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/61400](https://github.com/kubernetes/kubernetes/pull/61400)
|
||||
|
||||
* Exec authenticator plugin now supports TLS client certificates.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/61803](https://github.com/kubernetes/kubernetes/pull/61803)
|
||||
|
||||
* The discovery client now has a default request timeout of 32 seconds.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/62733](https://github.com/kubernetes/kubernetes/pull/62733)
|
||||
|
||||
* The OpenStack auth config from is now read from the client config. If the client config is not available, it falls back to reading from the environment variables.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/60200](https://github.com/kubernetes/kubernetes/pull/60200)
|
||||
|
||||
* The in-tree support for openstack credentials is now deprecated. Please use the `client-keystone-auth` from the cloud-provider-openstack repository. Details on how to use this new capability is documented [here](https://github.com/kubernetes/cloud-provider-openstack/blob/master/docs/using-client-keystone-auth.md)
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/64346](https://github.com/kubernetes/kubernetes/pull/64346)
|
||||
|
||||
**Bug fixes and Improvements:**
|
||||
|
||||
* 406 mime-type errors are now tolerated while attempting to load new openapi schema. This improves compatibility with older servers when creating/updating API objects.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/61949](https://github.com/kubernetes/kubernetes/pull/61949)
|
||||
|
||||
* Removes the generated `DeleteCollection()` method for `Services` since the API does not support it.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/63861](https://github.com/kubernetes/kubernetes/pull/63861)
|
||||
|
||||
* Event object references with apiversion now report an apiversion, instead of just the group.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/63913](https://github.com/kubernetes/kubernetes/pull/63913)
|
||||
|
||||
[https://github.com/kubernetes/kubernetes/pull/62462](https://github.com/kubernetes/kubernetes/pull/62462)
|
||||
|
||||
* [k8s.io/apimachinery] `runtime.Unstructured.UnstructuredContent()` no longer mutates the source while returning the contents.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/62063](https://github.com/kubernetes/kubernetes/pull/62063)
|
||||
|
||||
* [k8s.io/apimachinery] Incomplete support for `uint64` is now removed. This fixes a panic encountered while using `DeepCopyJSON` with `uint64`.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/62981](https://github.com/kubernetes/kubernetes/pull/62981)
|
||||
|
||||
* [k8s.io/apimachinery] API server can now parse `propagationPolicy` when it sent as a query parameter sent with a delete request.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/63414](https://github.com/kubernetes/kubernetes/pull/63414)
|
||||
|
||||
* [k8s.io/apimachinery] APIServices with kube-like versions (e.g. v1, v2beta1, etc.) will be sorted appropriately within each group.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/64004](https://github.com/kubernetes/kubernetes/pull/64004)
|
||||
|
||||
* [k8s.io/apimachinery] `int64` is the only allowed integer for printers.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/64639](https://github.com/kubernetes/kubernetes/pull/64639)
|
||||
|
||||
## API changes
|
||||
|
||||
**Breaking Changes:**
|
||||
|
||||
* Support for `alpha.kubernetes.io/nvidia-gpu` resource which was deprecated in 1.10 is removed. Please use the resource exposed by `DevicePlugins` instead (`nvidia.com/gpu`).
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/61498](https://github.com/kubernetes/kubernetes/pull/61498)
|
||||
|
||||
* Alpha annotation for `PersistentVolume` node affinity has been removed. Update your `PersistentVolume`s to use the beta `PersistentVolume.nodeAffinity` field before upgrading.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/61816](https://github.com/kubernetes/kubernetes/pull/61816)
|
||||
|
||||
* `ObjectMeta ` `ListOptions` `DeleteOptions` are removed from the core api group. Please use the ones in `meta/v1` instead.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/61809](https://github.com/kubernetes/kubernetes/pull/61809)
|
||||
|
||||
* `ExternalID` in `NodeSpec` is deprecated. The externalID of the node is no longer set in the Node spec.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/61877](https://github.com/kubernetes/kubernetes/pull/61877)
|
||||
|
||||
* PSP-related types in the `extensions/v1beta1` API group are now deprecated. It is suggested to use the `policy/v1beta1` API group instead.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/61777](https://github.com/kubernetes/kubernetes/pull/61777)
|
||||
|
||||
**New Features:**
|
||||
|
||||
* `PodSecurityPolicy` now supports restricting hostPath volume mounts to be readOnly and under specific path prefixes.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/58647](https://github.com/kubernetes/kubernetes/pull/58647)
|
||||
|
||||
* `Node.Spec.ConfigSource.ConfigMap.KubeletConfigKey` must be specified when using dynamic Kubelet config to tell the Kubelet which key of the `ConfigMap` identifies its config file.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/59847](https://github.com/kubernetes/kubernetes/pull/59847)
|
||||
|
||||
* `serverAddressByClientCIDRs` in `meta/v1` APIGroup is now optional.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/61963](https://github.com/kubernetes/kubernetes/pull/61963)
|
||||
|
||||
* A new field `MatchFields` is added to `NodeSelectorTerm`. Currently, it only supports `metadata.name`.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/62002](https://github.com/kubernetes/kubernetes/pull/62002)
|
||||
|
||||
* The `PriorityClass` API is promoted to `scheduling.k8s.io/v1beta1`.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/63100](https://github.com/kubernetes/kubernetes/pull/63100)
|
||||
|
||||
* The status of dynamic Kubelet config is now reported via `Node.Status.Config`, rather than the `KubeletConfigOk` node condition.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/63314](https://github.com/kubernetes/kubernetes/pull/63314)
|
||||
|
||||
* The `GitRepo` volume type is deprecated. To provision a container with a git repo, mount an `EmptyDir` into an `InitContainer` that clones the repo using git, then mount the `EmptyDir` into the Pod's container.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/63445](https://github.com/kubernetes/kubernetes/pull/63445)
|
||||
|
||||
* The Sysctls experimental feature has been promoted to beta (enabled by default via the `Sysctls` feature flag). `PodSecurityPolicy` and `Pod` objects now have fields for specifying and controlling sysctls. Alpha sysctl annotations will be ignored by 1.11+ kubelets. All alpha sysctl annotations in existing deployments must be converted to API fields to be effective.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/63717](https://github.com/kubernetes/kubernetes/pull/63717)
|
||||
|
||||
* The annotation `service.alpha.kubernetes.io/tolerate-unready-endpoints` is deprecated. Users should use `Service.spec.publishNotReadyAddresses` instead.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/63742](https://github.com/kubernetes/kubernetes/pull/63742)
|
||||
|
||||
* `VerticalPodAutoscaler` has been added to `autoscaling/v1` API group.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/63797](https://github.com/kubernetes/kubernetes/pull/63797)
|
||||
|
||||
* Alpha support is added for dynamic volume limits based on node type.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/64154](https://github.com/kubernetes/kubernetes/pull/64154)
|
||||
|
||||
* `ContainersReady` condition is added to the Pod status.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/64646](https://github.com/kubernetes/kubernetes/pull/64646)
|
||||
|
||||
**Bug fixes and Improvements:**
|
||||
|
||||
* Default mount propagation has changed from `HostToContainer` (`rslave` in Linux terminology) to `None` (`private`) to match the behavior in 1.9 and earlier releases. `HostToContainer` as a default caused regressions in some pods.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/62462](https://github.com/kubernetes/kubernetes/pull/62462)
|
||||
|
||||
# v7.0.0
|
||||
|
||||
**Breaking Changes:**
|
||||
|
||||
* Google Cloud Service Account email addresses can now be used in RBAC Role bindings since the default scopes now include the `userinfo.email` scope. This is a breaking change if the numeric uniqueIDs of the Google service accounts were being used in RBAC role bindings. The behavior can be overridden by explicitly specifying the scope values as comma-separated string in the `users[*].config.scopes` field in the `KUBECONFIG` file.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/58141](https://github.com/kubernetes/kubernetes/pull/58141)
|
||||
|
||||
* [k8s.io/api] The `ConfigOK` node condition has been renamed to `KubeletConfigOk`.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/59905](https://github.com/kubernetes/kubernetes/pull/59905)
|
||||
|
||||
**New Features:**
|
||||
|
||||
* Subresource support is added to the dynamic client.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/56717](https://github.com/kubernetes/kubernetes/pull/56717)
|
||||
|
||||
* A watch method is added to the Fake Client.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/57504](https://github.com/kubernetes/kubernetes/pull/57504)
|
||||
|
||||
* `ListOptions` can be modified when creating a `ListWatch`.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/57508](https://github.com/kubernetes/kubernetes/pull/57508)
|
||||
|
||||
* A `/token` subresource for ServiceAccount is added.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/58111](https://github.com/kubernetes/kubernetes/pull/58111)
|
||||
|
||||
* If an informer delivery fails, the particular notification is skipped and continued the next time.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/58394](https://github.com/kubernetes/kubernetes/pull/58394)
|
||||
|
||||
* Certificate manager will no longer wait until the initial rotation succeeds or fails before returning from `Start()`.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/58930](https://github.com/kubernetes/kubernetes/pull/58930)
|
||||
|
||||
* [k8s.io/api] `VolumeScheduling` and `LocalPersistentVolume` features are beta and enabled by default. The PersistentVolume NodeAffinity alpha annotation is deprecated and will be removed in a future release.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/59391](https://github.com/kubernetes/kubernetes/pull/59391)
|
||||
|
||||
* [k8s.io/api] The `PodSecurityPolicy` API has been moved to the `policy/v1beta1` API group. The `PodSecurityPolicy` API in the `extensions/v1beta1` API group is deprecated and will be removed in a future release.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/54933](https://github.com/kubernetes/kubernetes/pull/54933)
|
||||
|
||||
* [k8s.io/api] ConfigMap objects now support binary data via a new `binaryData` field.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/57938](https://github.com/kubernetes/kubernetes/pull/57938)
|
||||
|
||||
* [k8s.io/api] Service account TokenRequest API is added.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/58027](https://github.com/kubernetes/kubernetes/pull/58027)
|
||||
|
||||
* [k8s.io/api] FSType is added in CSI volume source to specify filesystems.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/58209](https://github.com/kubernetes/kubernetes/pull/58209)
|
||||
|
||||
* [k8s.io/api] v1beta1 VolumeAttachment API is added.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/58462](https://github.com/kubernetes/kubernetes/pull/58462)
|
||||
|
||||
* [k8s.io/api] `v1.Pod` now has a field `ShareProcessNamespace` to configure whether a single process namespace should be shared between all containers in a pod. This feature is in alpha preview.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/58716](https://github.com/kubernetes/kubernetes/pull/58716)
|
||||
|
||||
* [k8s.io/api] Add `NominatedNodeName` field to `PodStatus`. This field is set when a pod preempts other pods on the node.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/58990](https://github.com/kubernetes/kubernetes/pull/58990)
|
||||
|
||||
* [k8s.io/api] Promote `CSIPersistentVolumeSourc`e to beta.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/59157](https://github.com/kubernetes/kubernetes/pull/59157)
|
||||
|
||||
* [k8s.io/api] Promote `DNSPolicy` and `DNSConfig` in `PodSpec` to beta.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/59771](https://github.com/kubernetes/kubernetes/pull/59771)
|
||||
|
||||
* [k8s.io/api] External metric types are added to the HPA API.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/60096](https://github.com/kubernetes/kubernetes/pull/60096)
|
||||
|
||||
* [k8s.io/apimachinery] The `meta.k8s.io/v1alpha1` objects for retrieving tabular responses from the server (`Table`) or fetching just the `ObjectMeta` for an object (as `PartialObjectMetadata`) are now beta as part of `meta.k8s.io/v1beta1`. Clients may request alternate representations of normal Kubernetes objects by passing an `Accept` header like `application/json;as=Table;g=meta.k8s.io;v=v1beta1` or `application/json;as=PartialObjectMetadata;g=meta.k8s.io;v1=v1beta1`. Older servers will ignore this representation or return an error if it is not available. Clients may request fallback to the normal object by adding a non-qualified mime-type to their `Accept` header like `application/json` - the server will then respond with either the alternate representation if it is supported or the fallback mime-type which is the normal object response.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/59059](https://github.com/kubernetes/kubernetes/pull/59059)
|
||||
|
||||
|
||||
**Bug fixes and Improvements:**
|
||||
|
||||
* Port-forwarding of TCP6 ports is fixed.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/57457](https://github.com/kubernetes/kubernetes/pull/57457)
|
||||
|
||||
* A race condition in SharedInformer that could violate the sequential delivery guarantee and cause panics on shutdown is fixed.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/59828](https://github.com/kubernetes/kubernetes/pull/59828)
|
||||
|
||||
* [k8s.io/api] PersistentVolume flexVolume sources can now reference secrets in a namespace other than the PersistentVolumeClaim's namespace.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/56460](https://github.com/kubernetes/kubernetes/pull/56460)
|
||||
|
||||
* [k8s.io/apimachinery] YAMLDecoder Read can now return the number of bytes read.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/57000](https://github.com/kubernetes/kubernetes/pull/57000)
|
||||
|
||||
* [k8s.io/apimachinery] YAMLDecoder Read now tracks rest of buffer on `io.ErrShortBuffer`.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/58817](https://github.com/kubernetes/kubernetes/pull/58817)
|
||||
|
||||
* [k8s.io/apimachinery] Prompt required merge key in the error message while applying a strategic merge patch.
|
||||
|
||||
* [https://github.com/kubernetes/kubernetes/pull/57854](https://github.com/kubernetes/kubernetes/pull/57854)
|
||||
|
||||
# v6.0.0
|
||||
|
||||
**Breaking Changes:**
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
# Contributing guidelines
|
||||
|
||||
Do not open pull requests directly against this repository. They will be ignored. Instead, please open pull requests against [kubernetes/kubernetes](https://git.k8s.io/kubernetes/).
|
||||
The exception is changes to the `README.md` itself.
|
||||
Please follow the same [contributing guide](https://git.k8s.io/kubernetes/CONTRIBUTING.md) you would follow for any other pull request made to kubernetes/kubernetes.
|
||||
Do not open pull requests directly against this repository, they will be ignored. Instead, please open pull requests against [kubernetes/kubernetes](https://git.k8s.io/kubernetes/). Please follow the same [contributing guide](https://git.k8s.io/kubernetes/CONTRIBUTING.md) you would follow for any other pull request made to kubernetes/kubernetes.
|
||||
|
||||
This repository is published from [kubernetes/kubernetes/staging/src/k8s.io/client-go](https://git.k8s.io/kubernetes/staging/src/k8s.io/client-go) by the [kubernetes publishing-bot](https://git.k8s.io/publishing-bot).
|
||||
|
||||
|
||||
270
Godeps/Godeps.json
generated
270
Godeps/Godeps.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go",
|
||||
"GoVersion": "go1.10",
|
||||
"GoVersion": "go1.9",
|
||||
"GodepVersion": "v80",
|
||||
"Packages": [
|
||||
"./..."
|
||||
@@ -16,23 +16,19 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Azure/go-autorest/autorest",
|
||||
"Rev": "bca49d5b51a50dc5bb17bbf6204c711c6dbded06"
|
||||
"Rev": "d4e6b95c12a08b4de2d48b45d5b4d594e5d32fab"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Azure/go-autorest/autorest/adal",
|
||||
"Rev": "bca49d5b51a50dc5bb17bbf6204c711c6dbded06"
|
||||
"Rev": "d4e6b95c12a08b4de2d48b45d5b4d594e5d32fab"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Azure/go-autorest/autorest/azure",
|
||||
"Rev": "bca49d5b51a50dc5bb17bbf6204c711c6dbded06"
|
||||
"Rev": "d4e6b95c12a08b4de2d48b45d5b4d594e5d32fab"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Azure/go-autorest/autorest/date",
|
||||
"Rev": "bca49d5b51a50dc5bb17bbf6204c711c6dbded06"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Azure/go-autorest/version",
|
||||
"Rev": "bca49d5b51a50dc5bb17bbf6204c711c6dbded06"
|
||||
"Rev": "d4e6b95c12a08b4de2d48b45d5b4d594e5d32fab"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/davecgh/go-spew/spew",
|
||||
@@ -72,27 +68,23 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/golang/protobuf/proto",
|
||||
"Rev": "b4deda0973fb4c70b50d226b1af49f3da59f5265"
|
||||
"Rev": "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/golang/protobuf/ptypes",
|
||||
"Rev": "b4deda0973fb4c70b50d226b1af49f3da59f5265"
|
||||
"Rev": "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/golang/protobuf/ptypes/any",
|
||||
"Rev": "b4deda0973fb4c70b50d226b1af49f3da59f5265"
|
||||
"Rev": "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/golang/protobuf/ptypes/duration",
|
||||
"Rev": "b4deda0973fb4c70b50d226b1af49f3da59f5265"
|
||||
"Rev": "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/golang/protobuf/ptypes/timestamp",
|
||||
"Rev": "b4deda0973fb4c70b50d226b1af49f3da59f5265"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/btree",
|
||||
"Rev": "7d79101e329e5a3adf994758c578dab82b90c017"
|
||||
"Rev": "1643683e1b54a9e88ad26d98f81400c8c9d9f4f9"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/gofuzz",
|
||||
@@ -112,39 +104,31 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gophercloud/gophercloud",
|
||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
||||
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack",
|
||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
||||
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants",
|
||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
||||
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens",
|
||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
||||
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens",
|
||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
||||
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/utils",
|
||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
||||
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gophercloud/gophercloud/pagination",
|
||||
"Rev": "781450b3c4fcb4f5182bcc5133adb4b2e4a09d1d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gregjones/httpcache",
|
||||
"Rev": "787624de3eb7bd915c329cba748687a3b22666a6"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gregjones/httpcache/diskcache",
|
||||
"Rev": "787624de3eb7bd915c329cba748687a3b22666a6"
|
||||
"Rev": "6da026c32e2d622cc242d32984259c77237aefe1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/golang-lru",
|
||||
@@ -154,9 +138,13 @@
|
||||
"ImportPath": "github.com/hashicorp/golang-lru/simplelru",
|
||||
"Rev": "a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/howeyc/gopass",
|
||||
"Rev": "bf9dde6d0d2c004a008c27aaee91170c786f6db8"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/imdario/mergo",
|
||||
"Rev": "9316a62528ac99aaecb4e47eadd6dc8aa6533d58"
|
||||
"Rev": "6633656539c1639d9d78127b7d47c622b5d7b6dc"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/json-iterator/go",
|
||||
@@ -170,10 +158,6 @@
|
||||
"ImportPath": "github.com/modern-go/reflect2",
|
||||
"Rev": "05fbef0ca5da472bbf96c9322b84a53edc03c9fd"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/peterbourgon/diskv",
|
||||
"Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/pmezard/go-difflib/difflib",
|
||||
"Rev": "d8ed2627bdf02c080bf22230dbb337003b7aba2d"
|
||||
@@ -184,11 +168,11 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/stretchr/testify/assert",
|
||||
"Rev": "c679ae2cc0cb27ec3293fea7e254e47386f05d69"
|
||||
"Rev": "f6abca593680b2315d2075e0f5e2a9751e3f431a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/crypto/ssh/terminal",
|
||||
"Rev": "de0752318171da717af4ce24d0a2e8626afaeb11"
|
||||
"Rev": "81e90905daefcd6fd217b62423c0908922eadb30"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/net/context",
|
||||
@@ -272,339 +256,335 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/admissionregistration/v1alpha1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/admissionregistration/v1beta1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/apps/v1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/apps/v1beta1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/apps/v1beta2",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/authentication/v1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/authentication/v1beta1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/authorization/v1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/authorization/v1beta1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/autoscaling/v1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/autoscaling/v2beta1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/autoscaling/v2beta2",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/batch/v1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/batch/v1beta1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/batch/v2alpha1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/certificates/v1beta1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/coordination/v1beta1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/core/v1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/events/v1beta1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/extensions/v1beta1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/imagepolicy/v1alpha1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/networking/v1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/policy/v1beta1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/rbac/v1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/rbac/v1alpha1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/rbac/v1beta1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/scheduling/v1alpha1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/scheduling/v1beta1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/settings/v1alpha1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/storage/v1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/storage/v1alpha1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/api/storage/v1beta1",
|
||||
"Rev": "fd83cbc87e7632ccd8bbab63d2b673d4e0c631cc"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/apitesting",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/apitesting/fuzzer",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/apitesting/roundtrip",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "c89978d5f86d7427bef2fc7752732c8c60b1d188"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/equality",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/errors",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/meta",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/resource",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/testing",
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/testing/fuzzer",
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/testing/roundtrip",
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apimachinery",
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apimachinery/announced",
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apimachinery/registered",
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/fuzzer",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/internalversion",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1beta1",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/conversion",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/fields",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/labels",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/schema",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/json",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/protobuf",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/recognizer",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/streaming",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/versioning",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/selection",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/types",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/cache",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/clock",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/diff",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/errors",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/framer",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/httpstream",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/httpstream/spdy",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/intstr",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/json",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/mergepatch",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/naming",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/net",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/remotecommand",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/runtime",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/sets",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/validation",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/validation/field",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/wait",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/yaml",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/version",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/watch",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/netutil",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
|
||||
"Rev": "6dd46049f39503a1fc8d65de4bd566829e95faff"
|
||||
"Rev": "d49e237a2683fa6dc43a86c7b1b766e0219fb6e7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
|
||||
"Rev": "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803"
|
||||
"Rev": "39cb288412c48cb533ba4be5d6c28620b9a0c1b4"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ To install `client-go` and place its dependencies in your `$GOPATH`:
|
||||
```sh
|
||||
go get k8s.io/client-go/...
|
||||
cd $GOPATH/src/k8s.io/client-go
|
||||
git checkout v9.0.0 # replace v9.0.0 with the required version
|
||||
git checkout v6.0.0
|
||||
# cd 1.5 # only necessary with 1.5 and 1.4 clients.
|
||||
godep restore ./...
|
||||
```
|
||||
@@ -99,7 +99,7 @@ your project:
|
||||
package: ( your project's import path ) # e.g. github.com/foo/bar
|
||||
import:
|
||||
- package: k8s.io/client-go
|
||||
version: v9.0.0 # replace v9.0.0 with the required version
|
||||
version: v6.0.0
|
||||
```
|
||||
|
||||
Second, add a Go file that imports `client-go` somewhere in your project,
|
||||
@@ -132,7 +132,7 @@ requests can override the version manually in `glide.yaml`. For example:
|
||||
package: ( your project's import path ) # e.g. github.com/foo/bar
|
||||
import:
|
||||
- package: k8s.io/client-go
|
||||
version: v9.0.0 # replace v9.0.0 with the required version
|
||||
version: v6.0.0
|
||||
# Use a newer version of go-spew even though client-go wants an old one.
|
||||
- package: github.com/davecgh/go-spew
|
||||
version: v1.1.0
|
||||
|
||||
45
OWNERS
45
OWNERS
@@ -1,17 +1,44 @@
|
||||
approvers:
|
||||
- caesarxuchao
|
||||
- deads2k
|
||||
- krousey
|
||||
- lavalamp
|
||||
- liggitt
|
||||
- smarterclayton
|
||||
- sttts
|
||||
reviewers:
|
||||
- caesarxuchao
|
||||
- deads2k
|
||||
- lavalamp
|
||||
- liggitt
|
||||
- soltysh
|
||||
reviewers:
|
||||
- thockin
|
||||
- lavalamp
|
||||
- smarterclayton
|
||||
- wojtek-t
|
||||
- deads2k
|
||||
- yujuhong
|
||||
- derekwaynecarr
|
||||
- caesarxuchao
|
||||
- vishh
|
||||
- mikedanese
|
||||
- liggitt
|
||||
- nikhiljindal
|
||||
- gmarek
|
||||
- erictune
|
||||
- davidopp
|
||||
- pmorie
|
||||
- sttts
|
||||
- yliaog
|
||||
labels:
|
||||
- sig/api-machinery
|
||||
- dchen1107
|
||||
- saad-ali
|
||||
- zmerlynn
|
||||
- luxas
|
||||
- janetkuo
|
||||
- justinsb
|
||||
- roberthbailey
|
||||
- ncdc
|
||||
- tallclair
|
||||
- yifan-gu
|
||||
- eparis
|
||||
- mwielgus
|
||||
- timothysc
|
||||
- feiskyer
|
||||
- jlowdermilk
|
||||
- soltysh
|
||||
- piosz
|
||||
- jsafrane
|
||||
|
||||
33
README.md
33
README.md
@@ -2,9 +2,9 @@
|
||||
|
||||
Go clients for talking to a [kubernetes](http://kubernetes.io/) cluster.
|
||||
|
||||
We currently recommend using the v8.0.0 tag. See [INSTALL.md](/INSTALL.md) for
|
||||
We currently recommend using the v6.0.0 tag. See [INSTALL.md](/INSTALL.md) for
|
||||
detailed installation instructions. `go get k8s.io/client-go/...` works, but
|
||||
will build `master`, which doesn't handle the dependencies well.
|
||||
will give you head and doesn't handle the dependencies well.
|
||||
|
||||
[![BuildStatus Widget]][BuildStatus Result]
|
||||
[![GoReport Widget]][GoReport Status]
|
||||
@@ -91,17 +91,16 @@ We will backport bugfixes--but not new features--into older versions of
|
||||
|
||||
#### Compatibility matrix
|
||||
|
||||
| | Kubernetes 1.5 | Kubernetes 1.6 | Kubernetes 1.7 | Kubernetes 1.8 | Kubernetes 1.9 | Kubernetes 1.10 | Kubernetes 1.11 |
|
||||
|---------------------|----------------|----------------|----------------|----------------|----------------|-----------------|-----------------|
|
||||
| client-go 1.5 | - | - | - | - | - | - | - |
|
||||
| client-go 2.0 | ✓ | +- | +- | +- | +- | +- | +- |
|
||||
| client-go 3.0 | +- | ✓ | - | +- | +- | +- | +- |
|
||||
| client-go 4.0 | +- | +- | ✓ | +- | +- | +- | +- |
|
||||
| client-go 5.0 | +- | +- | +- | ✓ | +- | +- | +- |
|
||||
| client-go 6.0 | +- | +- | +- | +- | ✓ | +- | +- |
|
||||
| client-go 7.0 | +- | +- | +- | +- | +- | ✓ | +- |
|
||||
| client-go 8.0 | +- | +- | +- | +- | +- | +- | ✓ |
|
||||
| client-go HEAD | +- | +- | +- | +- | +- | +- | +- |
|
||||
| | Kubernetes 1.4 | Kubernetes 1.5 | Kubernetes 1.6 | Kubernetes 1.7 | Kubernetes 1.8 | Kubernetes 1.9 |
|
||||
|---------------------|----------------|----------------|----------------|----------------|----------------|----------------|
|
||||
| client-go 1.4 | ✓ | - | - | - | - | - |
|
||||
| client-go 1.5 | + | - | - | - | - | - |
|
||||
| client-go 2.0 | +- | ✓ | +- | +- | +- | +- |
|
||||
| client-go 3.0 | +- | +- | ✓ | - | +- | +- |
|
||||
| client-go 4.0 | +- | +- | +- | ✓ | +- | +- |
|
||||
| client-go 5.0 | +- | +- | +- | +- | ✓ | +- |
|
||||
| client-go 6.0 | +- | +- | +- | +- | +- | ✓ |
|
||||
| client-go HEAD | +- | +- | +- | +- | +- | + |
|
||||
|
||||
Key:
|
||||
|
||||
@@ -126,11 +125,9 @@ between client-go versions.
|
||||
| client-go 1.5 | Kubernetes main repo, 1.5 branch | = - |
|
||||
| client-go 2.0 | Kubernetes main repo, 1.5 branch | = - |
|
||||
| client-go 3.0 | Kubernetes main repo, 1.6 branch | = - |
|
||||
| client-go 4.0 | Kubernetes main repo, 1.7 branch | = - |
|
||||
| client-go 5.0 | Kubernetes main repo, 1.8 branch | = - |
|
||||
| client-go 4.0 | Kubernetes main repo, 1.7 branch | ✓ |
|
||||
| client-go 5.0 | Kubernetes main repo, 1.8 branch | ✓ |
|
||||
| client-go 6.0 | Kubernetes main repo, 1.9 branch | ✓ |
|
||||
| client-go 7.0 | Kubernetes main repo, 1.10 branch | ✓ |
|
||||
| client-go 8.0 | Kubernetes main repo, 1.11 branch | ✓ |
|
||||
| client-go HEAD | Kubernetes main repo, master branch | ✓ |
|
||||
|
||||
Key:
|
||||
@@ -155,7 +152,7 @@ existing users won't be broken.
|
||||
|
||||
### Kubernetes tags
|
||||
|
||||
This repository is still a mirror of
|
||||
As of October 2017, client-go is still a mirror of
|
||||
[k8s.io/kubernetes/staging/src/client-go](https://github.com/kubernetes/kubernetes/tree/master/staging/src/k8s.io/client-go),
|
||||
the code development is still done in the staging area. Since Kubernetes 1.8
|
||||
release, when syncing the code from the staging area, we also sync the Kubernetes
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
# Defined below are the security contacts for this repo.
|
||||
#
|
||||
# They are the contact point for the Product Security Team to reach out
|
||||
# to for triaging and handling of incoming issues.
|
||||
#
|
||||
# The below names agree to abide by the
|
||||
# [Embargo Policy](https://github.com/kubernetes/sig-release/blob/master/security-release-process-documentation/security-release-process.md#embargo-policy)
|
||||
# and will be removed and replaced if they violate that agreement.
|
||||
#
|
||||
# DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE
|
||||
# INSTRUCTIONS AT https://kubernetes.io/security/
|
||||
|
||||
cjcullen
|
||||
jessfraz
|
||||
liggitt
|
||||
philips
|
||||
tallclair
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
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 deprecated_dynamic
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// dynamicCodec is a codec that wraps the standard unstructured codec
|
||||
// with special handling for Status objects.
|
||||
// Deprecated only used by test code and its wrong
|
||||
type dynamicCodec struct{}
|
||||
|
||||
func (dynamicCodec) Decode(data []byte, gvk *schema.GroupVersionKind, obj runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
|
||||
obj, gvk, err := unstructured.UnstructuredJSONScheme.Decode(data, gvk, obj)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if _, ok := obj.(*metav1.Status); !ok && strings.ToLower(gvk.Kind) == "status" {
|
||||
obj = &metav1.Status{}
|
||||
err := json.Unmarshal(data, obj)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return obj, gvk, nil
|
||||
}
|
||||
|
||||
func (dynamicCodec) Encode(obj runtime.Object, w io.Writer) error {
|
||||
return unstructured.UnstructuredJSONScheme.Encode(obj, w)
|
||||
}
|
||||
|
||||
// ContentConfig returns a rest.ContentConfig for dynamic types.
|
||||
// Deprecated only used by test code and its wrong
|
||||
func ContentConfig() rest.ContentConfig {
|
||||
var jsonInfo runtime.SerializerInfo
|
||||
// TODO: scheme.Codecs here should become "pkg/apis/server/scheme" which is the minimal core you need
|
||||
// to talk to a kubernetes server
|
||||
for _, info := range scheme.Codecs.SupportedMediaTypes() {
|
||||
if info.MediaType == runtime.ContentTypeJSON {
|
||||
jsonInfo = info
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
jsonInfo.Serializer = dynamicCodec{}
|
||||
jsonInfo.PrettySerializer = nil
|
||||
return rest.ContentConfig{
|
||||
AcceptContentTypes: runtime.ContentTypeJSON,
|
||||
ContentType: runtime.ContentTypeJSON,
|
||||
NegotiatedSerializer: serializer.NegotiatedSerializerWrapper(jsonInfo),
|
||||
}
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 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 dynamic provides a client interface to arbitrary Kubernetes
|
||||
// APIs that exposes common high level operations and exposes common
|
||||
// metadata.
|
||||
package deprecated_dynamic
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"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"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// Interface is a Kubernetes client that allows you to access metadata
|
||||
// and manipulate metadata of a Kubernetes API group.
|
||||
type Interface interface {
|
||||
// Resource returns an API interface to the specified resource for this client's
|
||||
// group and version. If resource is not a namespaced resource, then namespace
|
||||
// is ignored. The ResourceInterface inherits the parameter codec of this client.
|
||||
Resource(resource *metav1.APIResource, namespace string) ResourceInterface
|
||||
}
|
||||
|
||||
// ResourceInterface is an API interface to a specific resource under a
|
||||
// dynamic client.
|
||||
type ResourceInterface interface {
|
||||
// List returns a list of objects for this resource.
|
||||
List(opts metav1.ListOptions) (runtime.Object, error)
|
||||
// Get gets the resource with the specified name.
|
||||
Get(name string, opts metav1.GetOptions) (*unstructured.Unstructured, error)
|
||||
// Delete deletes the resource with the specified name.
|
||||
Delete(name string, opts *metav1.DeleteOptions) error
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
DeleteCollection(deleteOptions *metav1.DeleteOptions, listOptions metav1.ListOptions) error
|
||||
// Create creates the provided resource.
|
||||
Create(obj *unstructured.Unstructured) (*unstructured.Unstructured, error)
|
||||
// Update updates the provided resource.
|
||||
Update(obj *unstructured.Unstructured) (*unstructured.Unstructured, error)
|
||||
// Watch returns a watch.Interface that watches the resource.
|
||||
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||
// Patch patches the provided resource.
|
||||
Patch(name string, pt types.PatchType, data []byte) (*unstructured.Unstructured, error)
|
||||
}
|
||||
|
||||
// Client is a Kubernetes client that allows you to access metadata
|
||||
// and manipulate metadata of a Kubernetes API group, and implements Interface.
|
||||
type Client struct {
|
||||
version schema.GroupVersion
|
||||
delegate dynamic.Interface
|
||||
}
|
||||
|
||||
// NewClient returns a new client based on the passed in config. The
|
||||
// codec is ignored, as the dynamic client uses it's own codec.
|
||||
func NewClient(conf *restclient.Config, version schema.GroupVersion) (*Client, error) {
|
||||
delegate, err := dynamic.NewForConfig(conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Client{version: version, delegate: delegate}, nil
|
||||
}
|
||||
|
||||
// Resource returns an API interface to the specified resource for this client's
|
||||
// group and version. If resource is not a namespaced resource, then namespace
|
||||
// is ignored. The ResourceInterface inherits the parameter codec of c.
|
||||
func (c *Client) Resource(resource *metav1.APIResource, namespace string) ResourceInterface {
|
||||
resourceTokens := strings.SplitN(resource.Name, "/", 2)
|
||||
subresources := []string{}
|
||||
if len(resourceTokens) > 1 {
|
||||
subresources = strings.Split(resourceTokens[1], "/")
|
||||
}
|
||||
|
||||
if len(namespace) == 0 {
|
||||
return oldResourceShim(c.delegate.Resource(c.version.WithResource(resourceTokens[0])), subresources)
|
||||
}
|
||||
return oldResourceShim(c.delegate.Resource(c.version.WithResource(resourceTokens[0])).Namespace(namespace), subresources)
|
||||
}
|
||||
|
||||
// the old interfaces used the wrong type for lists. this fixes that
|
||||
func oldResourceShim(in dynamic.ResourceInterface, subresources []string) ResourceInterface {
|
||||
return oldResourceShimType{ResourceInterface: in, subresources: subresources}
|
||||
}
|
||||
|
||||
type oldResourceShimType struct {
|
||||
dynamic.ResourceInterface
|
||||
subresources []string
|
||||
}
|
||||
|
||||
func (s oldResourceShimType) Create(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
||||
return s.ResourceInterface.Create(obj, metav1.CreateOptions{}, s.subresources...)
|
||||
}
|
||||
|
||||
func (s oldResourceShimType) Update(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
||||
return s.ResourceInterface.Update(obj, metav1.UpdateOptions{}, s.subresources...)
|
||||
}
|
||||
|
||||
func (s oldResourceShimType) Delete(name string, opts *metav1.DeleteOptions) error {
|
||||
return s.ResourceInterface.Delete(name, opts, s.subresources...)
|
||||
}
|
||||
|
||||
func (s oldResourceShimType) Get(name string, opts metav1.GetOptions) (*unstructured.Unstructured, error) {
|
||||
return s.ResourceInterface.Get(name, opts, s.subresources...)
|
||||
}
|
||||
|
||||
func (s oldResourceShimType) List(opts metav1.ListOptions) (runtime.Object, error) {
|
||||
return s.ResourceInterface.List(opts)
|
||||
}
|
||||
|
||||
func (s oldResourceShimType) Patch(name string, pt types.PatchType, data []byte) (*unstructured.Unstructured, error) {
|
||||
return s.ResourceInterface.Patch(name, pt, data, metav1.UpdateOptions{}, s.subresources...)
|
||||
}
|
||||
@@ -1,623 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 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 deprecated_dynamic
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/streaming"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
restclientwatch "k8s.io/client-go/rest/watch"
|
||||
)
|
||||
|
||||
func getJSON(version, kind, name string) []byte {
|
||||
return []byte(fmt.Sprintf(`{"apiVersion": %q, "kind": %q, "metadata": {"name": %q}}`, version, kind, name))
|
||||
}
|
||||
|
||||
func getListJSON(version, kind string, items ...[]byte) []byte {
|
||||
json := fmt.Sprintf(`{"apiVersion": %q, "kind": %q, "items": [%s]}`,
|
||||
version, kind, bytes.Join(items, []byte(",")))
|
||||
return []byte(json)
|
||||
}
|
||||
|
||||
func getObject(version, kind, name string) *unstructured.Unstructured {
|
||||
return &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": version,
|
||||
"kind": kind,
|
||||
"metadata": map[string]interface{}{
|
||||
"name": name,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func getClientServer(gv *schema.GroupVersion, h func(http.ResponseWriter, *http.Request)) (Interface, *httptest.Server, error) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(h))
|
||||
cl, err := NewClient(&restclient.Config{
|
||||
Host: srv.URL,
|
||||
ContentConfig: restclient.ContentConfig{GroupVersion: gv},
|
||||
}, *gv)
|
||||
if err != nil {
|
||||
srv.Close()
|
||||
return nil, nil, err
|
||||
}
|
||||
return cl, srv, nil
|
||||
}
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
tcs := []struct {
|
||||
name string
|
||||
namespace string
|
||||
path string
|
||||
resp []byte
|
||||
want *unstructured.UnstructuredList
|
||||
}{
|
||||
{
|
||||
name: "normal_list",
|
||||
path: "/apis/gtest/vtest/rtest",
|
||||
resp: getListJSON("vTest", "rTestList",
|
||||
getJSON("vTest", "rTest", "item1"),
|
||||
getJSON("vTest", "rTest", "item2")),
|
||||
want: &unstructured.UnstructuredList{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "vTest",
|
||||
"kind": "rTestList",
|
||||
},
|
||||
Items: []unstructured.Unstructured{
|
||||
*getObject("vTest", "rTest", "item1"),
|
||||
*getObject("vTest", "rTest", "item2"),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "namespaced_list",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest",
|
||||
resp: getListJSON("vTest", "rTestList",
|
||||
getJSON("vTest", "rTest", "item1"),
|
||||
getJSON("vTest", "rTest", "item2")),
|
||||
want: &unstructured.UnstructuredList{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "vTest",
|
||||
"kind": "rTestList",
|
||||
},
|
||||
Items: []unstructured.Unstructured{
|
||||
*getObject("vTest", "rTest", "item1"),
|
||||
*getObject("vTest", "rTest", "item2"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: "rtest", Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "GET" {
|
||||
t.Errorf("List(%q) got HTTP method %s. wanted GET", tc.name, r.Method)
|
||||
}
|
||||
|
||||
if r.URL.Path != tc.path {
|
||||
t.Errorf("List(%q) got path %s. wanted %s", tc.name, r.URL.Path, tc.path)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", runtime.ContentTypeJSON)
|
||||
w.Write(tc.resp)
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when creating client: %v", err)
|
||||
continue
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
got, err := cl.Resource(resource, tc.namespace).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when listing %q: %v", tc.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(got, tc.want) {
|
||||
t.Errorf("List(%q) want: %v\ngot: %v", tc.name, tc.want, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
tcs := []struct {
|
||||
resource string
|
||||
namespace string
|
||||
name string
|
||||
path string
|
||||
resp []byte
|
||||
want *unstructured.Unstructured
|
||||
}{
|
||||
{
|
||||
resource: "rtest",
|
||||
name: "normal_get",
|
||||
path: "/apis/gtest/vtest/rtest/normal_get",
|
||||
resp: getJSON("vTest", "rTest", "normal_get"),
|
||||
want: getObject("vTest", "rTest", "normal_get"),
|
||||
},
|
||||
{
|
||||
resource: "rtest",
|
||||
namespace: "nstest",
|
||||
name: "namespaced_get",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_get",
|
||||
resp: getJSON("vTest", "rTest", "namespaced_get"),
|
||||
want: getObject("vTest", "rTest", "namespaced_get"),
|
||||
},
|
||||
{
|
||||
resource: "rtest/srtest",
|
||||
name: "normal_subresource_get",
|
||||
path: "/apis/gtest/vtest/rtest/normal_subresource_get/srtest",
|
||||
resp: getJSON("vTest", "srTest", "normal_subresource_get"),
|
||||
want: getObject("vTest", "srTest", "normal_subresource_get"),
|
||||
},
|
||||
{
|
||||
resource: "rtest/srtest",
|
||||
namespace: "nstest",
|
||||
name: "namespaced_subresource_get",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_subresource_get/srtest",
|
||||
resp: getJSON("vTest", "srTest", "namespaced_subresource_get"),
|
||||
want: getObject("vTest", "srTest", "namespaced_subresource_get"),
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: tc.resource, Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "GET" {
|
||||
t.Errorf("Get(%q) got HTTP method %s. wanted GET", tc.name, r.Method)
|
||||
}
|
||||
|
||||
if r.URL.Path != tc.path {
|
||||
t.Errorf("Get(%q) got path %s. wanted %s", tc.name, r.URL.Path, tc.path)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", runtime.ContentTypeJSON)
|
||||
w.Write(tc.resp)
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when creating client: %v", err)
|
||||
continue
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
got, err := cl.Resource(resource, tc.namespace).Get(tc.name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when getting %q: %v", tc.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(got, tc.want) {
|
||||
t.Errorf("Get(%q) want: %v\ngot: %v", tc.name, tc.want, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
background := metav1.DeletePropagationBackground
|
||||
uid := types.UID("uid")
|
||||
|
||||
statusOK := &metav1.Status{
|
||||
TypeMeta: metav1.TypeMeta{Kind: "Status"},
|
||||
Status: metav1.StatusSuccess,
|
||||
}
|
||||
tcs := []struct {
|
||||
namespace string
|
||||
name string
|
||||
path string
|
||||
deleteOptions *metav1.DeleteOptions
|
||||
}{
|
||||
{
|
||||
name: "normal_delete",
|
||||
path: "/apis/gtest/vtest/rtest/normal_delete",
|
||||
},
|
||||
{
|
||||
namespace: "nstest",
|
||||
name: "namespaced_delete",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_delete",
|
||||
},
|
||||
{
|
||||
namespace: "nstest",
|
||||
name: "namespaced_delete_with_options",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_delete_with_options",
|
||||
deleteOptions: &metav1.DeleteOptions{Preconditions: &metav1.Preconditions{UID: &uid}, PropagationPolicy: &background},
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: "rtest", Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "DELETE" {
|
||||
t.Errorf("Delete(%q) got HTTP method %s. wanted DELETE", tc.name, r.Method)
|
||||
}
|
||||
|
||||
if r.URL.Path != tc.path {
|
||||
t.Errorf("Delete(%q) got path %s. wanted %s", tc.name, r.URL.Path, tc.path)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", runtime.ContentTypeJSON)
|
||||
unstructured.UnstructuredJSONScheme.Encode(statusOK, w)
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when creating client: %v", err)
|
||||
continue
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
err = cl.Resource(resource, tc.namespace).Delete(tc.name, tc.deleteOptions)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when deleting %q: %v", tc.name, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteCollection(t *testing.T) {
|
||||
statusOK := &metav1.Status{
|
||||
TypeMeta: metav1.TypeMeta{Kind: "Status"},
|
||||
Status: metav1.StatusSuccess,
|
||||
}
|
||||
tcs := []struct {
|
||||
namespace string
|
||||
name string
|
||||
path string
|
||||
}{
|
||||
{
|
||||
name: "normal_delete_collection",
|
||||
path: "/apis/gtest/vtest/rtest",
|
||||
},
|
||||
{
|
||||
namespace: "nstest",
|
||||
name: "namespaced_delete_collection",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: "rtest", Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "DELETE" {
|
||||
t.Errorf("DeleteCollection(%q) got HTTP method %s. wanted DELETE", tc.name, r.Method)
|
||||
}
|
||||
|
||||
if r.URL.Path != tc.path {
|
||||
t.Errorf("DeleteCollection(%q) got path %s. wanted %s", tc.name, r.URL.Path, tc.path)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", runtime.ContentTypeJSON)
|
||||
unstructured.UnstructuredJSONScheme.Encode(statusOK, w)
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when creating client: %v", err)
|
||||
continue
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
err = cl.Resource(resource, tc.namespace).DeleteCollection(nil, metav1.ListOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when deleting collection %q: %v", tc.name, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
tcs := []struct {
|
||||
resource string
|
||||
name string
|
||||
namespace string
|
||||
obj *unstructured.Unstructured
|
||||
path string
|
||||
}{
|
||||
{
|
||||
resource: "rtest",
|
||||
name: "normal_create",
|
||||
path: "/apis/gtest/vtest/rtest",
|
||||
obj: getObject("gtest/vTest", "rTest", "normal_create"),
|
||||
},
|
||||
{
|
||||
resource: "rtest",
|
||||
name: "namespaced_create",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest",
|
||||
obj: getObject("gtest/vTest", "rTest", "namespaced_create"),
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: tc.resource, Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "POST" {
|
||||
t.Errorf("Create(%q) got HTTP method %s. wanted POST", tc.name, r.Method)
|
||||
}
|
||||
|
||||
if r.URL.Path != tc.path {
|
||||
t.Errorf("Create(%q) got path %s. wanted %s", tc.name, r.URL.Path, tc.path)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", runtime.ContentTypeJSON)
|
||||
data, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
t.Errorf("Create(%q) unexpected error reading body: %v", tc.name, err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(data)
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when creating client: %v", err)
|
||||
continue
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
got, err := cl.Resource(resource, tc.namespace).Create(tc.obj)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when creating %q: %v", tc.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(got, tc.obj) {
|
||||
t.Errorf("Create(%q) want: %v\ngot: %v", tc.name, tc.obj, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdate(t *testing.T) {
|
||||
tcs := []struct {
|
||||
resource string
|
||||
name string
|
||||
namespace string
|
||||
obj *unstructured.Unstructured
|
||||
path string
|
||||
}{
|
||||
{
|
||||
resource: "rtest",
|
||||
name: "normal_update",
|
||||
path: "/apis/gtest/vtest/rtest/normal_update",
|
||||
obj: getObject("gtest/vTest", "rTest", "normal_update"),
|
||||
},
|
||||
{
|
||||
resource: "rtest",
|
||||
name: "namespaced_update",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_update",
|
||||
obj: getObject("gtest/vTest", "rTest", "namespaced_update"),
|
||||
},
|
||||
{
|
||||
resource: "rtest/srtest",
|
||||
name: "normal_subresource_update",
|
||||
path: "/apis/gtest/vtest/rtest/normal_update/srtest",
|
||||
obj: getObject("gtest/vTest", "srTest", "normal_update"),
|
||||
},
|
||||
{
|
||||
resource: "rtest/srtest",
|
||||
name: "namespaced_subresource_update",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_update/srtest",
|
||||
obj: getObject("gtest/vTest", "srTest", "namespaced_update"),
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: tc.resource, Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "PUT" {
|
||||
t.Errorf("Update(%q) got HTTP method %s. wanted PUT", tc.name, r.Method)
|
||||
}
|
||||
|
||||
if r.URL.Path != tc.path {
|
||||
t.Errorf("Update(%q) got path %s. wanted %s", tc.name, r.URL.Path, tc.path)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", runtime.ContentTypeJSON)
|
||||
data, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
t.Errorf("Update(%q) unexpected error reading body: %v", tc.name, err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(data)
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when creating client: %v", err)
|
||||
continue
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
got, err := cl.Resource(resource, tc.namespace).Update(tc.obj)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when updating %q: %v", tc.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(got, tc.obj) {
|
||||
t.Errorf("Update(%q) want: %v\ngot: %v", tc.name, tc.obj, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWatch(t *testing.T) {
|
||||
tcs := []struct {
|
||||
name string
|
||||
namespace string
|
||||
events []watch.Event
|
||||
path string
|
||||
query string
|
||||
}{
|
||||
{
|
||||
name: "normal_watch",
|
||||
path: "/apis/gtest/vtest/rtest",
|
||||
query: "watch=true",
|
||||
events: []watch.Event{
|
||||
{Type: watch.Added, Object: getObject("gtest/vTest", "rTest", "normal_watch")},
|
||||
{Type: watch.Modified, Object: getObject("gtest/vTest", "rTest", "normal_watch")},
|
||||
{Type: watch.Deleted, Object: getObject("gtest/vTest", "rTest", "normal_watch")},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "namespaced_watch",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest",
|
||||
query: "watch=true",
|
||||
events: []watch.Event{
|
||||
{Type: watch.Added, Object: getObject("gtest/vTest", "rTest", "namespaced_watch")},
|
||||
{Type: watch.Modified, Object: getObject("gtest/vTest", "rTest", "namespaced_watch")},
|
||||
{Type: watch.Deleted, Object: getObject("gtest/vTest", "rTest", "namespaced_watch")},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: "rtest", Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "GET" {
|
||||
t.Errorf("Watch(%q) got HTTP method %s. wanted GET", tc.name, r.Method)
|
||||
}
|
||||
|
||||
if r.URL.Path != tc.path {
|
||||
t.Errorf("Watch(%q) got path %s. wanted %s", tc.name, r.URL.Path, tc.path)
|
||||
}
|
||||
if r.URL.RawQuery != tc.query {
|
||||
t.Errorf("Watch(%q) got query %s. wanted %s", tc.name, r.URL.RawQuery, tc.query)
|
||||
}
|
||||
|
||||
enc := restclientwatch.NewEncoder(streaming.NewEncoder(w, dynamicCodec{}), dynamicCodec{})
|
||||
for _, e := range tc.events {
|
||||
enc.Encode(&e)
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when creating client: %v", err)
|
||||
continue
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
watcher, err := cl.Resource(resource, tc.namespace).Watch(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when watching %q: %v", tc.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, want := range tc.events {
|
||||
got := <-watcher.ResultChan()
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("Watch(%q) want: %v\ngot: %v", tc.name, want, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPatch(t *testing.T) {
|
||||
tcs := []struct {
|
||||
resource string
|
||||
name string
|
||||
namespace string
|
||||
patch []byte
|
||||
want *unstructured.Unstructured
|
||||
path string
|
||||
}{
|
||||
{
|
||||
resource: "rtest",
|
||||
name: "normal_patch",
|
||||
path: "/apis/gtest/vtest/rtest/normal_patch",
|
||||
patch: getJSON("gtest/vTest", "rTest", "normal_patch"),
|
||||
want: getObject("gtest/vTest", "rTest", "normal_patch"),
|
||||
},
|
||||
{
|
||||
resource: "rtest",
|
||||
name: "namespaced_patch",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_patch",
|
||||
patch: getJSON("gtest/vTest", "rTest", "namespaced_patch"),
|
||||
want: getObject("gtest/vTest", "rTest", "namespaced_patch"),
|
||||
},
|
||||
{
|
||||
resource: "rtest/srtest",
|
||||
name: "normal_subresource_patch",
|
||||
path: "/apis/gtest/vtest/rtest/normal_subresource_patch/srtest",
|
||||
patch: getJSON("gtest/vTest", "srTest", "normal_subresource_patch"),
|
||||
want: getObject("gtest/vTest", "srTest", "normal_subresource_patch"),
|
||||
},
|
||||
{
|
||||
resource: "rtest/srtest",
|
||||
name: "namespaced_subresource_patch",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_subresource_patch/srtest",
|
||||
patch: getJSON("gtest/vTest", "srTest", "namespaced_subresource_patch"),
|
||||
want: getObject("gtest/vTest", "srTest", "namespaced_subresource_patch"),
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: tc.resource, Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "PATCH" {
|
||||
t.Errorf("Patch(%q) got HTTP method %s. wanted PATCH", tc.name, r.Method)
|
||||
}
|
||||
|
||||
if r.URL.Path != tc.path {
|
||||
t.Errorf("Patch(%q) got path %s. wanted %s", tc.name, r.URL.Path, tc.path)
|
||||
}
|
||||
|
||||
content := r.Header.Get("Content-Type")
|
||||
if content != string(types.StrategicMergePatchType) {
|
||||
t.Errorf("Patch(%q) got Content-Type %s. wanted %s", tc.name, content, types.StrategicMergePatchType)
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
t.Errorf("Patch(%q) unexpected error reading body: %v", tc.name, err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(data)
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when creating client: %v", err)
|
||||
continue
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
got, err := cl.Resource(resource, tc.namespace).Patch(tc.name, types.StrategicMergePatchType, tc.patch)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when patching %q: %v", tc.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(got, tc.want) {
|
||||
t.Errorf("Patch(%q) want: %v\ngot: %v", tc.name, tc.want, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,7 +67,20 @@ func (d *memCacheClient) ServerResourcesForGroupVersion(groupVersion string) (*m
|
||||
|
||||
// ServerResources returns the supported resources for all groups and versions.
|
||||
func (d *memCacheClient) ServerResources() ([]*metav1.APIResourceList, error) {
|
||||
return discovery.ServerResources(d)
|
||||
apiGroups, err := d.ServerGroups()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groupVersions := metav1.ExtractGroupVersions(apiGroups)
|
||||
result := []*metav1.APIResourceList{}
|
||||
for _, groupVersion := range groupVersions {
|
||||
resources, err := d.ServerResourcesForGroupVersion(groupVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, resources)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (d *memCacheClient) ServerGroups() (*metav1.APIGroupList, error) {
|
||||
@@ -83,12 +96,18 @@ func (d *memCacheClient) RESTClient() restclient.Interface {
|
||||
return d.delegate.RESTClient()
|
||||
}
|
||||
|
||||
// TODO: Should this also be cached? The results seem more likely to be
|
||||
// inconsistent with ServerGroups and ServerResources given the requirement to
|
||||
// actively Invalidate.
|
||||
func (d *memCacheClient) ServerPreferredResources() ([]*metav1.APIResourceList, error) {
|
||||
return discovery.ServerPreferredResources(d)
|
||||
return d.delegate.ServerPreferredResources()
|
||||
}
|
||||
|
||||
// TODO: Should this also be cached? The results seem more likely to be
|
||||
// inconsistent with ServerGroups and ServerResources given the requirement to
|
||||
// actively Invalidate.
|
||||
func (d *memCacheClient) ServerPreferredNamespacedResources() ([]*metav1.APIResourceList, error) {
|
||||
return discovery.ServerPreferredNamespacedResources(d)
|
||||
return d.delegate.ServerPreferredNamespacedResources()
|
||||
}
|
||||
|
||||
func (d *memCacheClient) ServerVersion() (*version.Info, error) {
|
||||
|
||||
@@ -1,282 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 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 discovery
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/googleapis/gnostic/OpenAPIv2"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/version"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// CachedDiscoveryClient implements the functions that discovery server-supported API groups,
|
||||
// versions and resources.
|
||||
type CachedDiscoveryClient struct {
|
||||
delegate DiscoveryInterface
|
||||
|
||||
// cacheDirectory is the directory where discovery docs are held. It must be unique per host:port combination to work well.
|
||||
cacheDirectory string
|
||||
|
||||
// ttl is how long the cache should be considered valid
|
||||
ttl time.Duration
|
||||
|
||||
// mutex protects the variables below
|
||||
mutex sync.Mutex
|
||||
|
||||
// ourFiles are all filenames of cache files created by this process
|
||||
ourFiles map[string]struct{}
|
||||
// invalidated is true if all cache files should be ignored that are not ours (e.g. after Invalidate() was called)
|
||||
invalidated bool
|
||||
// fresh is true if all used cache files were ours
|
||||
fresh bool
|
||||
}
|
||||
|
||||
var _ CachedDiscoveryInterface = &CachedDiscoveryClient{}
|
||||
|
||||
// ServerResourcesForGroupVersion returns the supported resources for a group and version.
|
||||
func (d *CachedDiscoveryClient) ServerResourcesForGroupVersion(groupVersion string) (*metav1.APIResourceList, error) {
|
||||
filename := filepath.Join(d.cacheDirectory, groupVersion, "serverresources.json")
|
||||
cachedBytes, err := d.getCachedFile(filename)
|
||||
// don't fail on errors, we either don't have a file or won't be able to run the cached check. Either way we can fallback.
|
||||
if err == nil {
|
||||
cachedResources := &metav1.APIResourceList{}
|
||||
if err := runtime.DecodeInto(scheme.Codecs.UniversalDecoder(), cachedBytes, cachedResources); err == nil {
|
||||
glog.V(10).Infof("returning cached discovery info from %v", filename)
|
||||
return cachedResources, nil
|
||||
}
|
||||
}
|
||||
|
||||
liveResources, err := d.delegate.ServerResourcesForGroupVersion(groupVersion)
|
||||
if err != nil {
|
||||
glog.V(3).Infof("skipped caching discovery info due to %v", err)
|
||||
return liveResources, err
|
||||
}
|
||||
if liveResources == nil || len(liveResources.APIResources) == 0 {
|
||||
glog.V(3).Infof("skipped caching discovery info, no resources found")
|
||||
return liveResources, err
|
||||
}
|
||||
|
||||
if err := d.writeCachedFile(filename, liveResources); err != nil {
|
||||
glog.V(1).Infof("failed to write cache to %v due to %v", filename, err)
|
||||
}
|
||||
|
||||
return liveResources, nil
|
||||
}
|
||||
|
||||
// ServerResources returns the supported resources for all groups and versions.
|
||||
func (d *CachedDiscoveryClient) ServerResources() ([]*metav1.APIResourceList, error) {
|
||||
return ServerResources(d)
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) ServerGroups() (*metav1.APIGroupList, error) {
|
||||
filename := filepath.Join(d.cacheDirectory, "servergroups.json")
|
||||
cachedBytes, err := d.getCachedFile(filename)
|
||||
// don't fail on errors, we either don't have a file or won't be able to run the cached check. Either way we can fallback.
|
||||
if err == nil {
|
||||
cachedGroups := &metav1.APIGroupList{}
|
||||
if err := runtime.DecodeInto(scheme.Codecs.UniversalDecoder(), cachedBytes, cachedGroups); err == nil {
|
||||
glog.V(10).Infof("returning cached discovery info from %v", filename)
|
||||
return cachedGroups, nil
|
||||
}
|
||||
}
|
||||
|
||||
liveGroups, err := d.delegate.ServerGroups()
|
||||
if err != nil {
|
||||
glog.V(3).Infof("skipped caching discovery info due to %v", err)
|
||||
return liveGroups, err
|
||||
}
|
||||
if liveGroups == nil || len(liveGroups.Groups) == 0 {
|
||||
glog.V(3).Infof("skipped caching discovery info, no groups found")
|
||||
return liveGroups, err
|
||||
}
|
||||
|
||||
if err := d.writeCachedFile(filename, liveGroups); err != nil {
|
||||
glog.V(1).Infof("failed to write cache to %v due to %v", filename, err)
|
||||
}
|
||||
|
||||
return liveGroups, nil
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) getCachedFile(filename string) ([]byte, error) {
|
||||
// after invalidation ignore cache files not created by this process
|
||||
d.mutex.Lock()
|
||||
_, ourFile := d.ourFiles[filename]
|
||||
if d.invalidated && !ourFile {
|
||||
d.mutex.Unlock()
|
||||
return nil, errors.New("cache invalidated")
|
||||
}
|
||||
d.mutex.Unlock()
|
||||
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
fileInfo, err := file.Stat()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if time.Now().After(fileInfo.ModTime().Add(d.ttl)) {
|
||||
return nil, errors.New("cache expired")
|
||||
}
|
||||
|
||||
// the cache is present and its valid. Try to read and use it.
|
||||
cachedBytes, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
d.fresh = d.fresh && ourFile
|
||||
|
||||
return cachedBytes, nil
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) writeCachedFile(filename string, obj runtime.Object) error {
|
||||
if err := os.MkdirAll(filepath.Dir(filename), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bytes, err := runtime.Encode(scheme.Codecs.LegacyCodec(), obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := ioutil.TempFile(filepath.Dir(filename), filepath.Base(filename)+".")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.Remove(f.Name())
|
||||
_, err = f.Write(bytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = os.Chmod(f.Name(), 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
name := f.Name()
|
||||
err = f.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// atomic rename
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
err = os.Rename(name, filename)
|
||||
if err == nil {
|
||||
d.ourFiles[filename] = struct{}{}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) RESTClient() restclient.Interface {
|
||||
return d.delegate.RESTClient()
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) ServerPreferredResources() ([]*metav1.APIResourceList, error) {
|
||||
return ServerPreferredResources(d)
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) ServerPreferredNamespacedResources() ([]*metav1.APIResourceList, error) {
|
||||
return ServerPreferredNamespacedResources(d)
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) ServerVersion() (*version.Info, error) {
|
||||
return d.delegate.ServerVersion()
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) OpenAPISchema() (*openapi_v2.Document, error) {
|
||||
return d.delegate.OpenAPISchema()
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) Fresh() bool {
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
|
||||
return d.fresh
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) Invalidate() {
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
|
||||
d.ourFiles = map[string]struct{}{}
|
||||
d.fresh = true
|
||||
d.invalidated = true
|
||||
}
|
||||
|
||||
// NewCachedDiscoveryClientForConfig creates a new DiscoveryClient for the given config, and wraps
|
||||
// the created client in a CachedDiscoveryClient. The provided configuration is updated with a
|
||||
// custom transport that understands cache responses.
|
||||
// We receive two distinct cache directories for now, in order to preserve old behavior
|
||||
// which makes use of the --cache-dir flag value for storing cache data from the CacheRoundTripper,
|
||||
// and makes use of the hardcoded destination (~/.kube/cache/discovery/...) for storing
|
||||
// CachedDiscoveryClient cache data. If httpCacheDir is empty, the restconfig's transport will not
|
||||
// be updated with a roundtripper that understands cache responses.
|
||||
// If discoveryCacheDir is empty, cached server resource data will be looked up in the current directory.
|
||||
// TODO(juanvallejo): the value of "--cache-dir" should be honored. Consolidate discoveryCacheDir with httpCacheDir
|
||||
// so that server resources and http-cache data are stored in the same location, provided via config flags.
|
||||
func NewCachedDiscoveryClientForConfig(config *restclient.Config, discoveryCacheDir, httpCacheDir string, ttl time.Duration) (*CachedDiscoveryClient, error) {
|
||||
if len(httpCacheDir) > 0 {
|
||||
// update the given restconfig with a custom roundtripper that
|
||||
// understands how to handle cache responses.
|
||||
wt := config.WrapTransport
|
||||
config.WrapTransport = func(rt http.RoundTripper) http.RoundTripper {
|
||||
if wt != nil {
|
||||
rt = wt(rt)
|
||||
}
|
||||
return newCacheRoundTripper(httpCacheDir, rt)
|
||||
}
|
||||
}
|
||||
|
||||
discoveryClient, err := NewDiscoveryClientForConfig(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newCachedDiscoveryClient(discoveryClient, discoveryCacheDir, ttl), nil
|
||||
}
|
||||
|
||||
// NewCachedDiscoveryClient creates a new DiscoveryClient. cacheDirectory is the directory where discovery docs are held. It must be unique per host:port combination to work well.
|
||||
func newCachedDiscoveryClient(delegate DiscoveryInterface, cacheDirectory string, ttl time.Duration) *CachedDiscoveryClient {
|
||||
return &CachedDiscoveryClient{
|
||||
delegate: delegate,
|
||||
cacheDirectory: cacheDirectory,
|
||||
ttl: ttl,
|
||||
ourFiles: map[string]struct{}{},
|
||||
fresh: true,
|
||||
}
|
||||
}
|
||||
@@ -1,169 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 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 discovery
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/googleapis/gnostic/OpenAPIv2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/version"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/rest/fake"
|
||||
)
|
||||
|
||||
func TestCachedDiscoveryClient_Fresh(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
d, err := ioutil.TempDir("", "")
|
||||
assert.NoError(err)
|
||||
defer os.RemoveAll(d)
|
||||
|
||||
c := fakeDiscoveryClient{}
|
||||
cdc := newCachedDiscoveryClient(&c, d, 60*time.Second)
|
||||
assert.True(cdc.Fresh(), "should be fresh after creation")
|
||||
|
||||
cdc.ServerGroups()
|
||||
assert.True(cdc.Fresh(), "should be fresh after groups call without cache")
|
||||
assert.Equal(c.groupCalls, 1)
|
||||
|
||||
cdc.ServerGroups()
|
||||
assert.True(cdc.Fresh(), "should be fresh after another groups call")
|
||||
assert.Equal(c.groupCalls, 1)
|
||||
|
||||
cdc.ServerResources()
|
||||
assert.True(cdc.Fresh(), "should be fresh after resources call")
|
||||
assert.Equal(c.resourceCalls, 1)
|
||||
|
||||
cdc.ServerResources()
|
||||
assert.True(cdc.Fresh(), "should be fresh after another resources call")
|
||||
assert.Equal(c.resourceCalls, 1)
|
||||
|
||||
cdc = newCachedDiscoveryClient(&c, d, 60*time.Second)
|
||||
cdc.ServerGroups()
|
||||
assert.False(cdc.Fresh(), "should NOT be fresh after recreation with existing groups cache")
|
||||
assert.Equal(c.groupCalls, 1)
|
||||
|
||||
cdc.ServerResources()
|
||||
assert.False(cdc.Fresh(), "should NOT be fresh after recreation with existing resources cache")
|
||||
assert.Equal(c.resourceCalls, 1)
|
||||
|
||||
cdc.Invalidate()
|
||||
assert.True(cdc.Fresh(), "should be fresh after cache invalidation")
|
||||
|
||||
cdc.ServerResources()
|
||||
assert.True(cdc.Fresh(), "should ignore existing resources cache after invalidation")
|
||||
assert.Equal(c.resourceCalls, 2)
|
||||
}
|
||||
|
||||
func TestNewCachedDiscoveryClient_TTL(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
d, err := ioutil.TempDir("", "")
|
||||
assert.NoError(err)
|
||||
defer os.RemoveAll(d)
|
||||
|
||||
c := fakeDiscoveryClient{}
|
||||
cdc := newCachedDiscoveryClient(&c, d, 1*time.Nanosecond)
|
||||
cdc.ServerGroups()
|
||||
assert.Equal(c.groupCalls, 1)
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
cdc.ServerGroups()
|
||||
assert.Equal(c.groupCalls, 2)
|
||||
}
|
||||
|
||||
type fakeDiscoveryClient struct {
|
||||
groupCalls int
|
||||
resourceCalls int
|
||||
versionCalls int
|
||||
openAPICalls int
|
||||
|
||||
serverResourcesHandler func() ([]*metav1.APIResourceList, error)
|
||||
}
|
||||
|
||||
var _ DiscoveryInterface = &fakeDiscoveryClient{}
|
||||
|
||||
func (c *fakeDiscoveryClient) RESTClient() restclient.Interface {
|
||||
return &fake.RESTClient{}
|
||||
}
|
||||
|
||||
func (c *fakeDiscoveryClient) ServerGroups() (*metav1.APIGroupList, error) {
|
||||
c.groupCalls = c.groupCalls + 1
|
||||
return &metav1.APIGroupList{
|
||||
Groups: []metav1.APIGroup{
|
||||
{
|
||||
Name: "a",
|
||||
Versions: []metav1.GroupVersionForDiscovery{
|
||||
{
|
||||
GroupVersion: "a/v1",
|
||||
Version: "v1",
|
||||
},
|
||||
},
|
||||
PreferredVersion: metav1.GroupVersionForDiscovery{
|
||||
GroupVersion: "a/v1",
|
||||
Version: "v1",
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *fakeDiscoveryClient) ServerResourcesForGroupVersion(groupVersion string) (*metav1.APIResourceList, error) {
|
||||
c.resourceCalls = c.resourceCalls + 1
|
||||
if groupVersion == "a/v1" {
|
||||
return &metav1.APIResourceList{APIResources: []metav1.APIResource{{Name: "widgets", Kind: "Widget"}}}, nil
|
||||
}
|
||||
|
||||
return nil, errors.NewNotFound(schema.GroupResource{}, "")
|
||||
}
|
||||
|
||||
func (c *fakeDiscoveryClient) ServerResources() ([]*metav1.APIResourceList, error) {
|
||||
c.resourceCalls = c.resourceCalls + 1
|
||||
if c.serverResourcesHandler != nil {
|
||||
return c.serverResourcesHandler()
|
||||
}
|
||||
return []*metav1.APIResourceList{}, nil
|
||||
}
|
||||
|
||||
func (c *fakeDiscoveryClient) ServerPreferredResources() ([]*metav1.APIResourceList, error) {
|
||||
c.resourceCalls = c.resourceCalls + 1
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *fakeDiscoveryClient) ServerPreferredNamespacedResources() ([]*metav1.APIResourceList, error) {
|
||||
c.resourceCalls = c.resourceCalls + 1
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *fakeDiscoveryClient) ServerVersion() (*version.Info, error) {
|
||||
c.versionCalls = c.versionCalls + 1
|
||||
return &version.Info{}, nil
|
||||
}
|
||||
|
||||
func (c *fakeDiscoveryClient) OpenAPISchema() (*openapi_v2.Document, error) {
|
||||
c.openAPICalls = c.openAPICalls + 1
|
||||
return &openapi_v2.Document{}, nil
|
||||
}
|
||||
@@ -22,8 +22,6 @@ import (
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/googleapis/gnostic/OpenAPIv2"
|
||||
@@ -33,7 +31,6 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/version"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
@@ -44,9 +41,6 @@ const (
|
||||
defaultRetries = 2
|
||||
// protobuf mime type
|
||||
mimePb = "application/com.github.proto-openapi.spec.v2@v1.0+protobuf"
|
||||
// defaultTimeout is the maximum amount of time per request when no timeout has been set on a RESTClient.
|
||||
// Defaults to 32s in order to have a distinguishable length of time, relative to other timeouts that exist.
|
||||
defaultTimeout = 32 * time.Second
|
||||
)
|
||||
|
||||
// DiscoveryInterface holds the methods that discover server-supported API groups,
|
||||
@@ -189,7 +183,33 @@ func (d *DiscoveryClient) ServerResourcesForGroupVersion(groupVersion string) (r
|
||||
|
||||
// serverResources returns the supported resources for all groups and versions.
|
||||
func (d *DiscoveryClient) serverResources() ([]*metav1.APIResourceList, error) {
|
||||
return ServerResources(d)
|
||||
apiGroups, err := d.ServerGroups()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := []*metav1.APIResourceList{}
|
||||
failedGroups := make(map[schema.GroupVersion]error)
|
||||
|
||||
for _, apiGroup := range apiGroups.Groups {
|
||||
for _, version := range apiGroup.Versions {
|
||||
gv := schema.GroupVersion{Group: apiGroup.Name, Version: version.Version}
|
||||
resources, err := d.ServerResourcesForGroupVersion(version.GroupVersion)
|
||||
if err != nil {
|
||||
// TODO: maybe restrict this to NotFound errors
|
||||
failedGroups[gv] = err
|
||||
continue
|
||||
}
|
||||
|
||||
result = append(result, resources)
|
||||
}
|
||||
}
|
||||
|
||||
if len(failedGroups) == 0 {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
return result, &ErrGroupDiscoveryFailed{Groups: failedGroups}
|
||||
}
|
||||
|
||||
// ServerResources returns the supported resources for all groups and versions.
|
||||
@@ -222,46 +242,14 @@ func IsGroupDiscoveryFailedError(err error) bool {
|
||||
|
||||
// serverPreferredResources returns the supported resources with the version preferred by the server.
|
||||
func (d *DiscoveryClient) serverPreferredResources() ([]*metav1.APIResourceList, error) {
|
||||
return ServerPreferredResources(d)
|
||||
}
|
||||
|
||||
// ServerResources uses the provided discovery interface to look up supported resources for all groups and versions.
|
||||
func ServerResources(d DiscoveryInterface) ([]*metav1.APIResourceList, error) {
|
||||
apiGroups, err := d.ServerGroups()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
groupVersionResources, failedGroups := fetchGroupVersionResources(d, apiGroups)
|
||||
|
||||
// order results by group/version discovery order
|
||||
result := []*metav1.APIResourceList{}
|
||||
for _, apiGroup := range apiGroups.Groups {
|
||||
for _, version := range apiGroup.Versions {
|
||||
gv := schema.GroupVersion{Group: apiGroup.Name, Version: version.Version}
|
||||
if resources, ok := groupVersionResources[gv]; ok {
|
||||
result = append(result, resources)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(failedGroups) == 0 {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
return result, &ErrGroupDiscoveryFailed{Groups: failedGroups}
|
||||
}
|
||||
|
||||
// ServerPreferredResources uses the provided discovery interface to look up preferred resources
|
||||
func ServerPreferredResources(d DiscoveryInterface) ([]*metav1.APIResourceList, error) {
|
||||
serverGroupList, err := d.ServerGroups()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
groupVersionResources, failedGroups := fetchGroupVersionResources(d, serverGroupList)
|
||||
|
||||
result := []*metav1.APIResourceList{}
|
||||
failedGroups := make(map[schema.GroupVersion]error)
|
||||
|
||||
grVersions := map[schema.GroupResource]string{} // selected version of a GroupResource
|
||||
grApiResources := map[schema.GroupResource]*metav1.APIResource{} // selected APIResource for a GroupResource
|
||||
gvApiResourceLists := map[schema.GroupVersion]*metav1.APIResourceList{} // blueprint for a APIResourceList for later grouping
|
||||
@@ -269,9 +257,10 @@ func ServerPreferredResources(d DiscoveryInterface) ([]*metav1.APIResourceList,
|
||||
for _, apiGroup := range serverGroupList.Groups {
|
||||
for _, version := range apiGroup.Versions {
|
||||
groupVersion := schema.GroupVersion{Group: apiGroup.Name, Version: version.Version}
|
||||
|
||||
apiResourceList, ok := groupVersionResources[groupVersion]
|
||||
if !ok {
|
||||
apiResourceList, err := d.ServerResourcesForGroupVersion(version.GroupVersion)
|
||||
if err != nil {
|
||||
// TODO: maybe restrict this to NotFound errors
|
||||
failedGroups[groupVersion] = err
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -313,41 +302,6 @@ func ServerPreferredResources(d DiscoveryInterface) ([]*metav1.APIResourceList,
|
||||
return result, &ErrGroupDiscoveryFailed{Groups: failedGroups}
|
||||
}
|
||||
|
||||
// fetchServerResourcesForGroupVersions uses the discovery client to fetch the resources for the specified groups in parallel
|
||||
func fetchGroupVersionResources(d DiscoveryInterface, apiGroups *metav1.APIGroupList) (map[schema.GroupVersion]*metav1.APIResourceList, map[schema.GroupVersion]error) {
|
||||
groupVersionResources := make(map[schema.GroupVersion]*metav1.APIResourceList)
|
||||
failedGroups := make(map[schema.GroupVersion]error)
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
resultLock := &sync.Mutex{}
|
||||
for _, apiGroup := range apiGroups.Groups {
|
||||
for _, version := range apiGroup.Versions {
|
||||
groupVersion := schema.GroupVersion{Group: apiGroup.Name, Version: version.Version}
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
defer utilruntime.HandleCrash()
|
||||
|
||||
apiResourceList, err := d.ServerResourcesForGroupVersion(groupVersion.String())
|
||||
|
||||
// lock to record results
|
||||
resultLock.Lock()
|
||||
defer resultLock.Unlock()
|
||||
|
||||
if err != nil {
|
||||
// TODO: maybe restrict this to NotFound errors
|
||||
failedGroups[groupVersion] = err
|
||||
} else {
|
||||
groupVersionResources[groupVersion] = apiResourceList
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
return groupVersionResources, failedGroups
|
||||
}
|
||||
|
||||
// ServerPreferredResources returns the supported resources with the version preferred by the
|
||||
// server.
|
||||
func (d *DiscoveryClient) ServerPreferredResources() ([]*metav1.APIResourceList, error) {
|
||||
@@ -357,12 +311,7 @@ func (d *DiscoveryClient) ServerPreferredResources() ([]*metav1.APIResourceList,
|
||||
// ServerPreferredNamespacedResources returns the supported namespaced resources with the
|
||||
// version preferred by the server.
|
||||
func (d *DiscoveryClient) ServerPreferredNamespacedResources() ([]*metav1.APIResourceList, error) {
|
||||
return ServerPreferredNamespacedResources(d)
|
||||
}
|
||||
|
||||
// ServerPreferredNamespacedResources uses the provided discovery interface to look up preferred namespaced resources
|
||||
func ServerPreferredNamespacedResources(d DiscoveryInterface) ([]*metav1.APIResourceList, error) {
|
||||
all, err := ServerPreferredResources(d)
|
||||
all, err := d.ServerPreferredResources()
|
||||
return FilteredBy(ResourcePredicateFunc(func(groupVersion string, r *metav1.APIResource) bool {
|
||||
return r.Namespaced
|
||||
}), all), err
|
||||
@@ -424,9 +373,6 @@ func withRetries(maxRetries int, f func() ([]*metav1.APIResourceList, error)) ([
|
||||
func setDiscoveryDefaults(config *restclient.Config) error {
|
||||
config.APIPath = ""
|
||||
config.GroupVersion = nil
|
||||
if config.Timeout == 0 {
|
||||
config.Timeout = defaultTimeout
|
||||
}
|
||||
codec := runtime.NoopEncoder{Decoder: scheme.Codecs.UniversalDecoder()}
|
||||
config.NegotiatedSerializer = serializer.NegotiatedSerializerWrapper(runtime.SerializerInfo{Serializer: codec})
|
||||
if len(config.UserAgent) == 0 {
|
||||
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package discovery
|
||||
package discovery_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -27,13 +27,12 @@ import (
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/googleapis/gnostic/OpenAPIv2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/version"
|
||||
. "k8s.io/client-go/discovery"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
@@ -131,12 +130,6 @@ func TestGetServerGroupsWithBrokenServer(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimeoutIsSet(t *testing.T) {
|
||||
cfg := &restclient.Config{}
|
||||
setDiscoveryDefaults(cfg)
|
||||
assert.Equal(t, defaultTimeout, cfg.Timeout)
|
||||
}
|
||||
|
||||
func TestGetServerResourcesWithV1Server(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
var obj interface{}
|
||||
@@ -190,14 +183,6 @@ func TestGetServerResources(t *testing.T) {
|
||||
{Name: "jobs", Namespaced: true, Kind: "Job"},
|
||||
},
|
||||
}
|
||||
beta2 := metav1.APIResourceList{
|
||||
GroupVersion: "extensions/v1beta2",
|
||||
APIResources: []metav1.APIResource{
|
||||
{Name: "deployments", Namespaced: true, Kind: "Deployment"},
|
||||
{Name: "ingresses", Namespaced: true, Kind: "Ingress"},
|
||||
{Name: "jobs", Namespaced: true, Kind: "Job"},
|
||||
},
|
||||
}
|
||||
tests := []struct {
|
||||
resourcesList *metav1.APIResourceList
|
||||
path string
|
||||
@@ -230,8 +215,6 @@ func TestGetServerResources(t *testing.T) {
|
||||
list = &stable
|
||||
case "/apis/extensions/v1beta1":
|
||||
list = &beta
|
||||
case "/apis/extensions/v1beta2":
|
||||
list = &beta2
|
||||
case "/api":
|
||||
list = &metav1.APIVersions{
|
||||
Versions: []string{
|
||||
@@ -242,10 +225,8 @@ func TestGetServerResources(t *testing.T) {
|
||||
list = &metav1.APIGroupList{
|
||||
Groups: []metav1.APIGroup{
|
||||
{
|
||||
Name: "extensions",
|
||||
Versions: []metav1.GroupVersionForDiscovery{
|
||||
{GroupVersion: "extensions/v1beta1", Version: "v1beta1"},
|
||||
{GroupVersion: "extensions/v1beta2", Version: "v1beta2"},
|
||||
{GroupVersion: "extensions/v1beta1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -287,10 +268,11 @@ func TestGetServerResources(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
serverGroupVersions := groupVersions(serverResources)
|
||||
expectedGroupVersions := []string{"v1", "extensions/v1beta1", "extensions/v1beta2"}
|
||||
if !reflect.DeepEqual(expectedGroupVersions, serverGroupVersions) {
|
||||
t.Errorf("unexpected group versions: %v", diff.ObjectReflectDiff(expectedGroupVersions, serverGroupVersions))
|
||||
serverGroupVersions := sets.NewString(groupVersions(serverResources)...)
|
||||
for _, api := range []string{"v1", "extensions/v1beta1"} {
|
||||
if !serverGroupVersions.Has(api) {
|
||||
t.Errorf("missing expected api %q in %v", api, serverResources)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -636,7 +618,7 @@ func TestServerPreferredResourcesRetries(t *testing.T) {
|
||||
{
|
||||
Name: "extensions",
|
||||
Versions: []metav1.GroupVersionForDiscovery{
|
||||
{GroupVersion: "extensions/v1beta1", Version: "v1beta1"},
|
||||
{GroupVersion: "extensions/v1beta1"},
|
||||
},
|
||||
PreferredVersion: metav1.GroupVersionForDiscovery{
|
||||
GroupVersion: "extensions/v1beta1",
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
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 discovery provides ways to discover server-supported
|
||||
// API groups, versions and resources.
|
||||
package discovery
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package restmapper
|
||||
package discovery
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -24,7 +24,6 @@ import (
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/discovery"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
@@ -38,9 +37,9 @@ type APIGroupResources struct {
|
||||
VersionedResources map[string][]metav1.APIResource
|
||||
}
|
||||
|
||||
// NewDiscoveryRESTMapper returns a PriorityRESTMapper based on the discovered
|
||||
// NewRESTMapper returns a PriorityRESTMapper based on the discovered
|
||||
// groups and resources passed in.
|
||||
func NewDiscoveryRESTMapper(groupResources []*APIGroupResources) meta.RESTMapper {
|
||||
func NewRESTMapper(groupResources []*APIGroupResources, versionInterfaces meta.VersionInterfacesFunc) meta.RESTMapper {
|
||||
unionMapper := meta.MultiRESTMapper{}
|
||||
|
||||
var groupPriority []string
|
||||
@@ -91,7 +90,7 @@ func NewDiscoveryRESTMapper(groupResources []*APIGroupResources) meta.RESTMapper
|
||||
}
|
||||
|
||||
gv := schema.GroupVersion{Group: group.Group.Name, Version: discoveryVersion.Version}
|
||||
versionMapper := meta.NewDefaultRESTMapper([]schema.GroupVersion{gv})
|
||||
versionMapper := meta.NewDefaultRESTMapper([]schema.GroupVersion{gv}, versionInterfaces)
|
||||
|
||||
for _, resource := range resources {
|
||||
scope := meta.RESTScopeNamespace
|
||||
@@ -144,13 +143,10 @@ func NewDiscoveryRESTMapper(groupResources []*APIGroupResources) meta.RESTMapper
|
||||
|
||||
// GetAPIGroupResources uses the provided discovery client to gather
|
||||
// discovery information and populate a slice of APIGroupResources.
|
||||
func GetAPIGroupResources(cl discovery.DiscoveryInterface) ([]*APIGroupResources, error) {
|
||||
func GetAPIGroupResources(cl DiscoveryInterface) ([]*APIGroupResources, error) {
|
||||
apiGroups, err := cl.ServerGroups()
|
||||
if err != nil {
|
||||
if apiGroups == nil || len(apiGroups.Groups) == 0 {
|
||||
return nil, err
|
||||
}
|
||||
// TODO track the errors and update callers to handle partial errors.
|
||||
return nil, err
|
||||
}
|
||||
var result []*APIGroupResources
|
||||
for _, group := range apiGroups.Groups {
|
||||
@@ -163,9 +159,7 @@ func GetAPIGroupResources(cl discovery.DiscoveryInterface) ([]*APIGroupResources
|
||||
if err != nil {
|
||||
// continue as best we can
|
||||
// TODO track the errors and update callers to handle partial errors.
|
||||
if resources == nil || len(resources.APIResources) == 0 {
|
||||
continue
|
||||
}
|
||||
continue
|
||||
}
|
||||
groupResources.VersionedResources[version.Version] = resources.APIResources
|
||||
}
|
||||
@@ -178,17 +172,19 @@ func GetAPIGroupResources(cl discovery.DiscoveryInterface) ([]*APIGroupResources
|
||||
// initialization of the RESTMapper until the first mapping is
|
||||
// requested.
|
||||
type DeferredDiscoveryRESTMapper struct {
|
||||
initMu sync.Mutex
|
||||
delegate meta.RESTMapper
|
||||
cl discovery.CachedDiscoveryInterface
|
||||
initMu sync.Mutex
|
||||
delegate meta.RESTMapper
|
||||
cl CachedDiscoveryInterface
|
||||
versionInterface meta.VersionInterfacesFunc
|
||||
}
|
||||
|
||||
// NewDeferredDiscoveryRESTMapper returns a
|
||||
// DeferredDiscoveryRESTMapper that will lazily query the provided
|
||||
// client for discovery information to do REST mappings.
|
||||
func NewDeferredDiscoveryRESTMapper(cl discovery.CachedDiscoveryInterface) *DeferredDiscoveryRESTMapper {
|
||||
func NewDeferredDiscoveryRESTMapper(cl CachedDiscoveryInterface, versionInterface meta.VersionInterfacesFunc) *DeferredDiscoveryRESTMapper {
|
||||
return &DeferredDiscoveryRESTMapper{
|
||||
cl: cl,
|
||||
cl: cl,
|
||||
versionInterface: versionInterface,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,7 +201,7 @@ func (d *DeferredDiscoveryRESTMapper) getDelegate() (meta.RESTMapper, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
d.delegate = NewDiscoveryRESTMapper(groupResources)
|
||||
d.delegate = NewRESTMapper(groupResources, d.versionInterface)
|
||||
return d.delegate, err
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package restmapper
|
||||
package discovery_test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
@@ -94,7 +94,7 @@ func TestRESTMapper(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
restMapper := NewDiscoveryRESTMapper(resources)
|
||||
restMapper := NewRESTMapper(resources, nil)
|
||||
|
||||
kindTCs := []struct {
|
||||
input schema.GroupVersionResource
|
||||
@@ -243,7 +243,7 @@ func TestDeferredDiscoveryRESTMapper_CacheMiss(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
cdc := fakeCachedDiscoveryInterface{fresh: false}
|
||||
m := NewDeferredDiscoveryRESTMapper(&cdc)
|
||||
m := NewDeferredDiscoveryRESTMapper(&cdc, nil)
|
||||
assert.False(cdc.fresh, "should NOT be fresh after instantiation")
|
||||
assert.Zero(cdc.invalidateCalls, "should not have called Invalidate()")
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 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 discovery
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/gregjones/httpcache"
|
||||
"github.com/gregjones/httpcache/diskcache"
|
||||
"github.com/peterbourgon/diskv"
|
||||
)
|
||||
|
||||
type cacheRoundTripper struct {
|
||||
rt *httpcache.Transport
|
||||
}
|
||||
|
||||
// newCacheRoundTripper creates a roundtripper that reads the ETag on
|
||||
// response headers and send the If-None-Match header on subsequent
|
||||
// corresponding requests.
|
||||
func newCacheRoundTripper(cacheDir string, rt http.RoundTripper) http.RoundTripper {
|
||||
d := diskv.New(diskv.Options{
|
||||
BasePath: cacheDir,
|
||||
TempDir: filepath.Join(cacheDir, ".diskv-temp"),
|
||||
})
|
||||
t := httpcache.NewTransport(diskcache.NewWithDiskv(d))
|
||||
t.Transport = rt
|
||||
|
||||
return &cacheRoundTripper{rt: t}
|
||||
}
|
||||
|
||||
func (rt *cacheRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
return rt.rt.RoundTrip(req)
|
||||
}
|
||||
|
||||
func (rt *cacheRoundTripper) CancelRequest(req *http.Request) {
|
||||
type canceler interface {
|
||||
CancelRequest(*http.Request)
|
||||
}
|
||||
if cr, ok := rt.rt.Transport.(canceler); ok {
|
||||
cr.CancelRequest(req)
|
||||
} else {
|
||||
glog.Errorf("CancelRequest not implemented by %T", rt.rt.Transport)
|
||||
}
|
||||
}
|
||||
|
||||
func (rt *cacheRoundTripper) WrappedRoundTripper() http.RoundTripper { return rt.rt.Transport }
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 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 discovery
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// copied from k8s.io/client-go/transport/round_trippers_test.go
|
||||
type testRoundTripper struct {
|
||||
Request *http.Request
|
||||
Response *http.Response
|
||||
Err error
|
||||
}
|
||||
|
||||
func (rt *testRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
rt.Request = req
|
||||
return rt.Response, rt.Err
|
||||
}
|
||||
|
||||
func TestCacheRoundTripper(t *testing.T) {
|
||||
rt := &testRoundTripper{}
|
||||
cacheDir, err := ioutil.TempDir("", "cache-rt")
|
||||
defer os.RemoveAll(cacheDir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cache := newCacheRoundTripper(cacheDir, rt)
|
||||
|
||||
// First call, caches the response
|
||||
req := &http.Request{
|
||||
Method: http.MethodGet,
|
||||
URL: &url.URL{Host: "localhost"},
|
||||
}
|
||||
rt.Response = &http.Response{
|
||||
Header: http.Header{"ETag": []string{`"123456"`}},
|
||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("Content"))),
|
||||
StatusCode: http.StatusOK,
|
||||
}
|
||||
resp, err := cache.RoundTrip(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
content, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(content) != "Content" {
|
||||
t.Errorf(`Expected Body to be "Content", got %q`, string(content))
|
||||
}
|
||||
|
||||
// Second call, returns cached response
|
||||
req = &http.Request{
|
||||
Method: http.MethodGet,
|
||||
URL: &url.URL{Host: "localhost"},
|
||||
}
|
||||
rt.Response = &http.Response{
|
||||
StatusCode: http.StatusNotModified,
|
||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("Other Content"))),
|
||||
}
|
||||
|
||||
resp, err = cache.RoundTrip(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Read body and make sure we have the initial content
|
||||
content, err = ioutil.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(content) != "Content" {
|
||||
t.Errorf("Invalid content read from cache %q", string(content))
|
||||
}
|
||||
}
|
||||
95
discovery/unstructured.go
Normal file
95
discovery/unstructured.go
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
Copyright 2016 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 discovery
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// UnstructuredObjectTyper provides a runtime.ObjectTyper implementation for
|
||||
// runtime.Unstructured object based on discovery information.
|
||||
type UnstructuredObjectTyper struct {
|
||||
registered map[schema.GroupVersionKind]bool
|
||||
typers []runtime.ObjectTyper
|
||||
}
|
||||
|
||||
// NewUnstructuredObjectTyper returns a runtime.ObjectTyper for
|
||||
// unstructured objects based on discovery information. It accepts a list of fallback typers
|
||||
// for handling objects that are not runtime.Unstructured. It does not delegate the Recognizes
|
||||
// check, only ObjectKinds.
|
||||
func NewUnstructuredObjectTyper(groupResources []*APIGroupResources, typers ...runtime.ObjectTyper) *UnstructuredObjectTyper {
|
||||
dot := &UnstructuredObjectTyper{
|
||||
registered: make(map[schema.GroupVersionKind]bool),
|
||||
typers: typers,
|
||||
}
|
||||
for _, group := range groupResources {
|
||||
for _, discoveryVersion := range group.Group.Versions {
|
||||
resources, ok := group.VersionedResources[discoveryVersion.Version]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
gv := schema.GroupVersion{Group: group.Group.Name, Version: discoveryVersion.Version}
|
||||
for _, resource := range resources {
|
||||
dot.registered[gv.WithKind(resource.Kind)] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return dot
|
||||
}
|
||||
|
||||
// ObjectKinds returns a slice of one element with the group,version,kind of the
|
||||
// provided object, or an error if the object is not runtime.Unstructured or
|
||||
// has no group,version,kind information. unversionedType will always be false
|
||||
// because runtime.Unstructured object should always have group,version,kind
|
||||
// information set.
|
||||
func (d *UnstructuredObjectTyper) ObjectKinds(obj runtime.Object) (gvks []schema.GroupVersionKind, unversionedType bool, err error) {
|
||||
if _, ok := obj.(runtime.Unstructured); ok {
|
||||
gvk := obj.GetObjectKind().GroupVersionKind()
|
||||
if len(gvk.Kind) == 0 {
|
||||
return nil, false, runtime.NewMissingKindErr("object has no kind field ")
|
||||
}
|
||||
if len(gvk.Version) == 0 {
|
||||
return nil, false, runtime.NewMissingVersionErr("object has no apiVersion field")
|
||||
}
|
||||
return []schema.GroupVersionKind{gvk}, false, nil
|
||||
}
|
||||
var lastErr error
|
||||
for _, typer := range d.typers {
|
||||
gvks, unversioned, err := typer.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
lastErr = err
|
||||
continue
|
||||
}
|
||||
return gvks, unversioned, nil
|
||||
}
|
||||
if lastErr == nil {
|
||||
lastErr = runtime.NewNotRegisteredErrForType(reflect.TypeOf(obj))
|
||||
}
|
||||
return nil, false, lastErr
|
||||
}
|
||||
|
||||
// Recognizes returns true if the provided group,version,kind was in the
|
||||
// discovery information.
|
||||
func (d *UnstructuredObjectTyper) Recognizes(gvk schema.GroupVersionKind) bool {
|
||||
return d.registered[gvk]
|
||||
}
|
||||
|
||||
var _ runtime.ObjectTyper = &UnstructuredObjectTyper{}
|
||||
379
dynamic/client.go
Normal file
379
dynamic/client.go
Normal file
@@ -0,0 +1,379 @@
|
||||
/*
|
||||
Copyright 2016 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 dynamic provides a client interface to arbitrary Kubernetes
|
||||
// APIs that exposes common high level operations and exposes common
|
||||
// metadata.
|
||||
package dynamic
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/conversion/queryparams"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
)
|
||||
|
||||
// Interface is a Kubernetes client that allows you to access metadata
|
||||
// and manipulate metadata of a Kubernetes API group.
|
||||
type Interface interface {
|
||||
// GetRateLimiter returns the rate limiter for this client.
|
||||
GetRateLimiter() flowcontrol.RateLimiter
|
||||
// Resource returns an API interface to the specified resource for this client's
|
||||
// group and version. If resource is not a namespaced resource, then namespace
|
||||
// is ignored. The ResourceInterface inherits the parameter codec of this client.
|
||||
Resource(resource *metav1.APIResource, namespace string) ResourceInterface
|
||||
// ParameterCodec returns a client with the provided parameter codec.
|
||||
ParameterCodec(parameterCodec runtime.ParameterCodec) Interface
|
||||
}
|
||||
|
||||
// ResourceInterface is an API interface to a specific resource under a
|
||||
// dynamic client.
|
||||
type ResourceInterface interface {
|
||||
// List returns a list of objects for this resource.
|
||||
List(opts metav1.ListOptions) (runtime.Object, error)
|
||||
// Get gets the resource with the specified name.
|
||||
Get(name string, opts metav1.GetOptions) (*unstructured.Unstructured, error)
|
||||
// Delete deletes the resource with the specified name.
|
||||
Delete(name string, opts *metav1.DeleteOptions) error
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
DeleteCollection(deleteOptions *metav1.DeleteOptions, listOptions metav1.ListOptions) error
|
||||
// Create creates the provided resource.
|
||||
Create(obj *unstructured.Unstructured) (*unstructured.Unstructured, error)
|
||||
// Update updates the provided resource.
|
||||
Update(obj *unstructured.Unstructured) (*unstructured.Unstructured, error)
|
||||
// Watch returns a watch.Interface that watches the resource.
|
||||
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||
// Patch patches the provided resource.
|
||||
Patch(name string, pt types.PatchType, data []byte) (*unstructured.Unstructured, error)
|
||||
}
|
||||
|
||||
// Client is a Kubernetes client that allows you to access metadata
|
||||
// and manipulate metadata of a Kubernetes API group, and implements Interface.
|
||||
type Client struct {
|
||||
cl *restclient.RESTClient
|
||||
parameterCodec runtime.ParameterCodec
|
||||
}
|
||||
|
||||
// NewClient returns a new client based on the passed in config. The
|
||||
// codec is ignored, as the dynamic client uses it's own codec.
|
||||
func NewClient(conf *restclient.Config) (*Client, error) {
|
||||
// avoid changing the original config
|
||||
confCopy := *conf
|
||||
conf = &confCopy
|
||||
|
||||
contentConfig := ContentConfig()
|
||||
contentConfig.GroupVersion = conf.GroupVersion
|
||||
if conf.NegotiatedSerializer != nil {
|
||||
contentConfig.NegotiatedSerializer = conf.NegotiatedSerializer
|
||||
}
|
||||
conf.ContentConfig = contentConfig
|
||||
|
||||
if conf.APIPath == "" {
|
||||
conf.APIPath = "/api"
|
||||
}
|
||||
|
||||
if len(conf.UserAgent) == 0 {
|
||||
conf.UserAgent = restclient.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
cl, err := restclient.RESTClientFor(conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Client{cl: cl}, nil
|
||||
}
|
||||
|
||||
// GetRateLimiter returns rate limier.
|
||||
func (c *Client) GetRateLimiter() flowcontrol.RateLimiter {
|
||||
return c.cl.GetRateLimiter()
|
||||
}
|
||||
|
||||
// Resource returns an API interface to the specified resource for this client's
|
||||
// group and version. If resource is not a namespaced resource, then namespace
|
||||
// is ignored. The ResourceInterface inherits the parameter codec of c.
|
||||
func (c *Client) Resource(resource *metav1.APIResource, namespace string) ResourceInterface {
|
||||
return &ResourceClient{
|
||||
cl: c.cl,
|
||||
resource: resource,
|
||||
ns: namespace,
|
||||
parameterCodec: c.parameterCodec,
|
||||
}
|
||||
}
|
||||
|
||||
// ParameterCodec returns a client with the provided parameter codec.
|
||||
func (c *Client) ParameterCodec(parameterCodec runtime.ParameterCodec) Interface {
|
||||
return &Client{
|
||||
cl: c.cl,
|
||||
parameterCodec: parameterCodec,
|
||||
}
|
||||
}
|
||||
|
||||
// ResourceClient is an API interface to a specific resource under a
|
||||
// dynamic client, and implements ResourceInterface.
|
||||
type ResourceClient struct {
|
||||
cl *restclient.RESTClient
|
||||
resource *metav1.APIResource
|
||||
ns string
|
||||
parameterCodec runtime.ParameterCodec
|
||||
}
|
||||
|
||||
func (rc *ResourceClient) parseResourceSubresourceName() (string, []string) {
|
||||
var resourceName string
|
||||
var subresourceName []string
|
||||
if strings.Contains(rc.resource.Name, "/") {
|
||||
resourceName = strings.Split(rc.resource.Name, "/")[0]
|
||||
subresourceName = strings.Split(rc.resource.Name, "/")[1:]
|
||||
} else {
|
||||
resourceName = rc.resource.Name
|
||||
}
|
||||
|
||||
return resourceName, subresourceName
|
||||
}
|
||||
|
||||
// List returns a list of objects for this resource.
|
||||
func (rc *ResourceClient) List(opts metav1.ListOptions) (runtime.Object, error) {
|
||||
parameterEncoder := rc.parameterCodec
|
||||
if parameterEncoder == nil {
|
||||
parameterEncoder = defaultParameterEncoder
|
||||
}
|
||||
return rc.cl.Get().
|
||||
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
|
||||
Resource(rc.resource.Name).
|
||||
VersionedParams(&opts, parameterEncoder).
|
||||
Do().
|
||||
Get()
|
||||
}
|
||||
|
||||
// Get gets the resource with the specified name.
|
||||
func (rc *ResourceClient) Get(name string, opts metav1.GetOptions) (*unstructured.Unstructured, error) {
|
||||
parameterEncoder := rc.parameterCodec
|
||||
if parameterEncoder == nil {
|
||||
parameterEncoder = defaultParameterEncoder
|
||||
}
|
||||
result := new(unstructured.Unstructured)
|
||||
resourceName, subresourceName := rc.parseResourceSubresourceName()
|
||||
err := rc.cl.Get().
|
||||
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
|
||||
Resource(resourceName).
|
||||
SubResource(subresourceName...).
|
||||
VersionedParams(&opts, parameterEncoder).
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Delete deletes the resource with the specified name.
|
||||
func (rc *ResourceClient) Delete(name string, opts *metav1.DeleteOptions) error {
|
||||
return rc.cl.Delete().
|
||||
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
|
||||
Resource(rc.resource.Name).
|
||||
Name(name).
|
||||
Body(opts).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (rc *ResourceClient) DeleteCollection(deleteOptions *metav1.DeleteOptions, listOptions metav1.ListOptions) error {
|
||||
parameterEncoder := rc.parameterCodec
|
||||
if parameterEncoder == nil {
|
||||
parameterEncoder = defaultParameterEncoder
|
||||
}
|
||||
return rc.cl.Delete().
|
||||
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
|
||||
Resource(rc.resource.Name).
|
||||
VersionedParams(&listOptions, parameterEncoder).
|
||||
Body(deleteOptions).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Create creates the provided resource.
|
||||
func (rc *ResourceClient) Create(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
||||
result := new(unstructured.Unstructured)
|
||||
resourceName, subresourceName := rc.parseResourceSubresourceName()
|
||||
req := rc.cl.Post().
|
||||
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
|
||||
Resource(resourceName).
|
||||
Body(obj)
|
||||
if len(subresourceName) > 0 {
|
||||
// If the provided resource is a subresource, the POST request should contain
|
||||
// object name. Examples of subresources that support Create operation:
|
||||
// core/v1/pods/{name}/binding
|
||||
// core/v1/pods/{name}/eviction
|
||||
// extensions/v1beta1/deployments/{name}/rollback
|
||||
// apps/v1beta1/deployments/{name}/rollback
|
||||
// NOTE: Currently our system assumes every subresource object has the same
|
||||
// name as the parent resource object. E.g. a pods/binding object having
|
||||
// metadada.name "foo" means pod "foo" is being bound. We may need to
|
||||
// change this if we break the assumption in the future.
|
||||
req = req.SubResource(subresourceName...).
|
||||
Name(obj.GetName())
|
||||
}
|
||||
err := req.Do().
|
||||
Into(result)
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Update updates the provided resource.
|
||||
func (rc *ResourceClient) Update(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
||||
result := new(unstructured.Unstructured)
|
||||
if len(obj.GetName()) == 0 {
|
||||
return result, errors.New("object missing name")
|
||||
}
|
||||
resourceName, subresourceName := rc.parseResourceSubresourceName()
|
||||
err := rc.cl.Put().
|
||||
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
|
||||
Resource(resourceName).
|
||||
SubResource(subresourceName...).
|
||||
// NOTE: Currently our system assumes every subresource object has the same
|
||||
// name as the parent resource object. E.g. a pods/binding object having
|
||||
// metadada.name "foo" means pod "foo" is being bound. We may need to
|
||||
// change this if we break the assumption in the future.
|
||||
Name(obj.GetName()).
|
||||
Body(obj).
|
||||
Do().
|
||||
Into(result)
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the resource.
|
||||
func (rc *ResourceClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
parameterEncoder := rc.parameterCodec
|
||||
if parameterEncoder == nil {
|
||||
parameterEncoder = defaultParameterEncoder
|
||||
}
|
||||
opts.Watch = true
|
||||
return rc.cl.Get().
|
||||
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
|
||||
Resource(rc.resource.Name).
|
||||
VersionedParams(&opts, parameterEncoder).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched resource.
|
||||
func (rc *ResourceClient) Patch(name string, pt types.PatchType, data []byte) (*unstructured.Unstructured, error) {
|
||||
result := new(unstructured.Unstructured)
|
||||
resourceName, subresourceName := rc.parseResourceSubresourceName()
|
||||
err := rc.cl.Patch(pt).
|
||||
NamespaceIfScoped(rc.ns, rc.resource.Namespaced).
|
||||
Resource(resourceName).
|
||||
SubResource(subresourceName...).
|
||||
Name(name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return result, err
|
||||
}
|
||||
|
||||
// dynamicCodec is a codec that wraps the standard unstructured codec
|
||||
// with special handling for Status objects.
|
||||
type dynamicCodec struct{}
|
||||
|
||||
func (dynamicCodec) Decode(data []byte, gvk *schema.GroupVersionKind, obj runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
|
||||
obj, gvk, err := unstructured.UnstructuredJSONScheme.Decode(data, gvk, obj)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if _, ok := obj.(*metav1.Status); !ok && strings.ToLower(gvk.Kind) == "status" {
|
||||
obj = &metav1.Status{}
|
||||
err := json.Unmarshal(data, obj)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return obj, gvk, nil
|
||||
}
|
||||
|
||||
func (dynamicCodec) Encode(obj runtime.Object, w io.Writer) error {
|
||||
return unstructured.UnstructuredJSONScheme.Encode(obj, w)
|
||||
}
|
||||
|
||||
// ContentConfig returns a restclient.ContentConfig for dynamic types.
|
||||
func ContentConfig() restclient.ContentConfig {
|
||||
var jsonInfo runtime.SerializerInfo
|
||||
// TODO: scheme.Codecs here should become "pkg/apis/server/scheme" which is the minimal core you need
|
||||
// to talk to a kubernetes server
|
||||
for _, info := range scheme.Codecs.SupportedMediaTypes() {
|
||||
if info.MediaType == runtime.ContentTypeJSON {
|
||||
jsonInfo = info
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
jsonInfo.Serializer = dynamicCodec{}
|
||||
jsonInfo.PrettySerializer = nil
|
||||
return restclient.ContentConfig{
|
||||
AcceptContentTypes: runtime.ContentTypeJSON,
|
||||
ContentType: runtime.ContentTypeJSON,
|
||||
NegotiatedSerializer: serializer.NegotiatedSerializerWrapper(jsonInfo),
|
||||
}
|
||||
}
|
||||
|
||||
// paramaterCodec is a codec converts an API object to query
|
||||
// parameters without trying to convert to the target version.
|
||||
type parameterCodec struct{}
|
||||
|
||||
func (parameterCodec) EncodeParameters(obj runtime.Object, to schema.GroupVersion) (url.Values, error) {
|
||||
return queryparams.Convert(obj)
|
||||
}
|
||||
|
||||
func (parameterCodec) DecodeParameters(parameters url.Values, from schema.GroupVersion, into runtime.Object) error {
|
||||
return errors.New("DecodeParameters not implemented on dynamic parameterCodec")
|
||||
}
|
||||
|
||||
var defaultParameterEncoder runtime.ParameterCodec = parameterCodec{}
|
||||
|
||||
type versionedParameterEncoderWithV1Fallback struct{}
|
||||
|
||||
func (versionedParameterEncoderWithV1Fallback) EncodeParameters(obj runtime.Object, to schema.GroupVersion) (url.Values, error) {
|
||||
ret, err := scheme.ParameterCodec.EncodeParameters(obj, to)
|
||||
if err != nil && runtime.IsNotRegisteredError(err) {
|
||||
// fallback to v1
|
||||
return scheme.ParameterCodec.EncodeParameters(obj, v1.SchemeGroupVersion)
|
||||
}
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (versionedParameterEncoderWithV1Fallback) DecodeParameters(parameters url.Values, from schema.GroupVersion, into runtime.Object) error {
|
||||
return errors.New("DecodeParameters not implemented on versionedParameterEncoderWithV1Fallback")
|
||||
}
|
||||
|
||||
// VersionedParameterEncoderWithV1Fallback is useful for encoding query
|
||||
// parameters for custom resources. It tries to convert object to the
|
||||
// specified version before converting it to query parameters, and falls back to
|
||||
// converting to v1 if the object is not registered in the specified version.
|
||||
// For the record, currently API server always treats query parameters sent to a
|
||||
// custom resource endpoint as v1.
|
||||
var VersionedParameterEncoderWithV1Fallback runtime.ParameterCodec = versionedParameterEncoderWithV1Fallback{}
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package deprecated_dynamic
|
||||
package dynamic
|
||||
|
||||
import (
|
||||
"sync"
|
||||
@@ -113,7 +113,7 @@ func (c *clientPoolImpl) ClientForGroupVersionKind(kind schema.GroupVersionKind)
|
||||
// we need to make a client
|
||||
conf.GroupVersion = &gv
|
||||
|
||||
dynamicClient, err := NewClient(conf, gv)
|
||||
dynamicClient, err := NewClient(conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -58,10 +58,11 @@ func getObject(version, kind, name string) *unstructured.Unstructured {
|
||||
}
|
||||
}
|
||||
|
||||
func getClientServer(h func(http.ResponseWriter, *http.Request)) (Interface, *httptest.Server, error) {
|
||||
func getClientServer(gv *schema.GroupVersion, h func(http.ResponseWriter, *http.Request)) (Interface, *httptest.Server, error) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(h))
|
||||
cl, err := NewForConfig(&restclient.Config{
|
||||
Host: srv.URL,
|
||||
cl, err := NewClient(&restclient.Config{
|
||||
Host: srv.URL,
|
||||
ContentConfig: restclient.ContentConfig{GroupVersion: gv},
|
||||
})
|
||||
if err != nil {
|
||||
srv.Close()
|
||||
@@ -80,7 +81,7 @@ func TestList(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "normal_list",
|
||||
path: "/apis/gtest/vtest/rtest",
|
||||
path: "/api/gtest/vtest/rtest",
|
||||
resp: getListJSON("vTest", "rTestList",
|
||||
getJSON("vTest", "rTest", "item1"),
|
||||
getJSON("vTest", "rTest", "item2")),
|
||||
@@ -98,7 +99,7 @@ func TestList(t *testing.T) {
|
||||
{
|
||||
name: "namespaced_list",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest",
|
||||
path: "/api/gtest/vtest/namespaces/nstest/rtest",
|
||||
resp: getListJSON("vTest", "rTestList",
|
||||
getJSON("vTest", "rTest", "item1"),
|
||||
getJSON("vTest", "rTest", "item2")),
|
||||
@@ -115,8 +116,9 @@ func TestList(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
resource := schema.GroupVersionResource{Group: "gtest", Version: "vtest", Resource: "rtest"}
|
||||
cl, srv, err := getClientServer(func(w http.ResponseWriter, r *http.Request) {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: "rtest", Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "GET" {
|
||||
t.Errorf("List(%q) got HTTP method %s. wanted GET", tc.name, r.Method)
|
||||
}
|
||||
@@ -134,7 +136,7 @@ func TestList(t *testing.T) {
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
got, err := cl.Resource(resource).Namespace(tc.namespace).List(metav1.ListOptions{})
|
||||
got, err := cl.Resource(resource, tc.namespace).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when listing %q: %v", tc.name, err)
|
||||
continue
|
||||
@@ -148,18 +150,17 @@ func TestList(t *testing.T) {
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
tcs := []struct {
|
||||
resource string
|
||||
subresource []string
|
||||
namespace string
|
||||
name string
|
||||
path string
|
||||
resp []byte
|
||||
want *unstructured.Unstructured
|
||||
resource string
|
||||
namespace string
|
||||
name string
|
||||
path string
|
||||
resp []byte
|
||||
want *unstructured.Unstructured
|
||||
}{
|
||||
{
|
||||
resource: "rtest",
|
||||
name: "normal_get",
|
||||
path: "/apis/gtest/vtest/rtest/normal_get",
|
||||
path: "/api/gtest/vtest/rtest/normal_get",
|
||||
resp: getJSON("vTest", "rTest", "normal_get"),
|
||||
want: getObject("vTest", "rTest", "normal_get"),
|
||||
},
|
||||
@@ -167,31 +168,30 @@ func TestGet(t *testing.T) {
|
||||
resource: "rtest",
|
||||
namespace: "nstest",
|
||||
name: "namespaced_get",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_get",
|
||||
path: "/api/gtest/vtest/namespaces/nstest/rtest/namespaced_get",
|
||||
resp: getJSON("vTest", "rTest", "namespaced_get"),
|
||||
want: getObject("vTest", "rTest", "namespaced_get"),
|
||||
},
|
||||
{
|
||||
resource: "rtest",
|
||||
subresource: []string{"srtest"},
|
||||
name: "normal_subresource_get",
|
||||
path: "/apis/gtest/vtest/rtest/normal_subresource_get/srtest",
|
||||
resp: getJSON("vTest", "srTest", "normal_subresource_get"),
|
||||
want: getObject("vTest", "srTest", "normal_subresource_get"),
|
||||
resource: "rtest/srtest",
|
||||
name: "normal_subresource_get",
|
||||
path: "/api/gtest/vtest/rtest/normal_subresource_get/srtest",
|
||||
resp: getJSON("vTest", "srTest", "normal_subresource_get"),
|
||||
want: getObject("vTest", "srTest", "normal_subresource_get"),
|
||||
},
|
||||
{
|
||||
resource: "rtest",
|
||||
subresource: []string{"srtest"},
|
||||
namespace: "nstest",
|
||||
name: "namespaced_subresource_get",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_subresource_get/srtest",
|
||||
resp: getJSON("vTest", "srTest", "namespaced_subresource_get"),
|
||||
want: getObject("vTest", "srTest", "namespaced_subresource_get"),
|
||||
resource: "rtest/srtest",
|
||||
namespace: "nstest",
|
||||
name: "namespaced_subresource_get",
|
||||
path: "/api/gtest/vtest/namespaces/nstest/rtest/namespaced_subresource_get/srtest",
|
||||
resp: getJSON("vTest", "srTest", "namespaced_subresource_get"),
|
||||
want: getObject("vTest", "srTest", "namespaced_subresource_get"),
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
resource := schema.GroupVersionResource{Group: "gtest", Version: "vtest", Resource: tc.resource}
|
||||
cl, srv, err := getClientServer(func(w http.ResponseWriter, r *http.Request) {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: tc.resource, Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "GET" {
|
||||
t.Errorf("Get(%q) got HTTP method %s. wanted GET", tc.name, r.Method)
|
||||
}
|
||||
@@ -209,7 +209,7 @@ func TestGet(t *testing.T) {
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
got, err := cl.Resource(resource).Namespace(tc.namespace).Get(tc.name, metav1.GetOptions{}, tc.subresource...)
|
||||
got, err := cl.Resource(resource, tc.namespace).Get(tc.name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when getting %q: %v", tc.name, err)
|
||||
continue
|
||||
@@ -222,50 +222,29 @@ func TestGet(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
background := metav1.DeletePropagationBackground
|
||||
uid := types.UID("uid")
|
||||
|
||||
statusOK := &metav1.Status{
|
||||
TypeMeta: metav1.TypeMeta{Kind: "Status"},
|
||||
Status: metav1.StatusSuccess,
|
||||
}
|
||||
tcs := []struct {
|
||||
subresource []string
|
||||
namespace string
|
||||
name string
|
||||
path string
|
||||
deleteOptions *metav1.DeleteOptions
|
||||
namespace string
|
||||
name string
|
||||
path string
|
||||
}{
|
||||
{
|
||||
name: "normal_delete",
|
||||
path: "/apis/gtest/vtest/rtest/normal_delete",
|
||||
path: "/api/gtest/vtest/rtest/normal_delete",
|
||||
},
|
||||
{
|
||||
namespace: "nstest",
|
||||
name: "namespaced_delete",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_delete",
|
||||
},
|
||||
{
|
||||
subresource: []string{"srtest"},
|
||||
name: "normal_delete",
|
||||
path: "/apis/gtest/vtest/rtest/normal_delete/srtest",
|
||||
},
|
||||
{
|
||||
subresource: []string{"srtest"},
|
||||
namespace: "nstest",
|
||||
name: "namespaced_delete",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_delete/srtest",
|
||||
},
|
||||
{
|
||||
namespace: "nstest",
|
||||
name: "namespaced_delete_with_options",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_delete_with_options",
|
||||
deleteOptions: &metav1.DeleteOptions{Preconditions: &metav1.Preconditions{UID: &uid}, PropagationPolicy: &background},
|
||||
path: "/api/gtest/vtest/namespaces/nstest/rtest/namespaced_delete",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
resource := schema.GroupVersionResource{Group: "gtest", Version: "vtest", Resource: "rtest"}
|
||||
cl, srv, err := getClientServer(func(w http.ResponseWriter, r *http.Request) {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: "rtest", Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "DELETE" {
|
||||
t.Errorf("Delete(%q) got HTTP method %s. wanted DELETE", tc.name, r.Method)
|
||||
}
|
||||
@@ -283,7 +262,7 @@ func TestDelete(t *testing.T) {
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
err = cl.Resource(resource).Namespace(tc.namespace).Delete(tc.name, tc.deleteOptions, tc.subresource...)
|
||||
err = cl.Resource(resource, tc.namespace).Delete(tc.name, nil)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when deleting %q: %v", tc.name, err)
|
||||
continue
|
||||
@@ -303,17 +282,18 @@ func TestDeleteCollection(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "normal_delete_collection",
|
||||
path: "/apis/gtest/vtest/rtest",
|
||||
path: "/api/gtest/vtest/rtest",
|
||||
},
|
||||
{
|
||||
namespace: "nstest",
|
||||
name: "namespaced_delete_collection",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest",
|
||||
path: "/api/gtest/vtest/namespaces/nstest/rtest",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
resource := schema.GroupVersionResource{Group: "gtest", Version: "vtest", Resource: "rtest"}
|
||||
cl, srv, err := getClientServer(func(w http.ResponseWriter, r *http.Request) {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: "rtest", Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "DELETE" {
|
||||
t.Errorf("DeleteCollection(%q) got HTTP method %s. wanted DELETE", tc.name, r.Method)
|
||||
}
|
||||
@@ -331,7 +311,7 @@ func TestDeleteCollection(t *testing.T) {
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
err = cl.Resource(resource).Namespace(tc.namespace).DeleteCollection(nil, metav1.ListOptions{})
|
||||
err = cl.Resource(resource, tc.namespace).DeleteCollection(nil, metav1.ListOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when deleting collection %q: %v", tc.name, err)
|
||||
continue
|
||||
@@ -341,45 +321,43 @@ func TestDeleteCollection(t *testing.T) {
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
tcs := []struct {
|
||||
resource string
|
||||
subresource []string
|
||||
name string
|
||||
namespace string
|
||||
obj *unstructured.Unstructured
|
||||
path string
|
||||
resource string
|
||||
name string
|
||||
namespace string
|
||||
obj *unstructured.Unstructured
|
||||
path string
|
||||
}{
|
||||
{
|
||||
resource: "rtest",
|
||||
name: "normal_create",
|
||||
path: "/apis/gtest/vtest/rtest",
|
||||
obj: getObject("gtest/vTest", "rTest", "normal_create"),
|
||||
path: "/api/gtest/vtest/rtest",
|
||||
obj: getObject("vTest", "rTest", "normal_create"),
|
||||
},
|
||||
{
|
||||
resource: "rtest",
|
||||
name: "namespaced_create",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest",
|
||||
obj: getObject("gtest/vTest", "rTest", "namespaced_create"),
|
||||
path: "/api/gtest/vtest/namespaces/nstest/rtest",
|
||||
obj: getObject("vTest", "rTest", "namespaced_create"),
|
||||
},
|
||||
{
|
||||
resource: "rtest",
|
||||
subresource: []string{"srtest"},
|
||||
name: "normal_subresource_create",
|
||||
path: "/apis/gtest/vtest/rtest/normal_subresource_create/srtest",
|
||||
obj: getObject("vTest", "srTest", "normal_subresource_create"),
|
||||
resource: "rtest/srtest",
|
||||
name: "normal_subresource_create",
|
||||
path: "/api/gtest/vtest/rtest/normal_subresource_create/srtest",
|
||||
obj: getObject("vTest", "srTest", "normal_subresource_create"),
|
||||
},
|
||||
{
|
||||
resource: "rtest/",
|
||||
subresource: []string{"srtest"},
|
||||
name: "namespaced_subresource_create",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_subresource_create/srtest",
|
||||
obj: getObject("vTest", "srTest", "namespaced_subresource_create"),
|
||||
resource: "rtest/srtest",
|
||||
name: "namespaced_subresource_create",
|
||||
namespace: "nstest",
|
||||
path: "/api/gtest/vtest/namespaces/nstest/rtest/namespaced_subresource_create/srtest",
|
||||
obj: getObject("vTest", "srTest", "namespaced_subresource_create"),
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
resource := schema.GroupVersionResource{Group: "gtest", Version: "vtest", Resource: tc.resource}
|
||||
cl, srv, err := getClientServer(func(w http.ResponseWriter, r *http.Request) {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: tc.resource, Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "POST" {
|
||||
t.Errorf("Create(%q) got HTTP method %s. wanted POST", tc.name, r.Method)
|
||||
}
|
||||
@@ -404,7 +382,7 @@ func TestCreate(t *testing.T) {
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
got, err := cl.Resource(resource).Namespace(tc.namespace).Create(tc.obj, metav1.CreateOptions{}, tc.subresource...)
|
||||
got, err := cl.Resource(resource, tc.namespace).Create(tc.obj)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when creating %q: %v", tc.name, err)
|
||||
continue
|
||||
@@ -418,45 +396,43 @@ func TestCreate(t *testing.T) {
|
||||
|
||||
func TestUpdate(t *testing.T) {
|
||||
tcs := []struct {
|
||||
resource string
|
||||
subresource []string
|
||||
name string
|
||||
namespace string
|
||||
obj *unstructured.Unstructured
|
||||
path string
|
||||
resource string
|
||||
name string
|
||||
namespace string
|
||||
obj *unstructured.Unstructured
|
||||
path string
|
||||
}{
|
||||
{
|
||||
resource: "rtest",
|
||||
name: "normal_update",
|
||||
path: "/apis/gtest/vtest/rtest/normal_update",
|
||||
obj: getObject("gtest/vTest", "rTest", "normal_update"),
|
||||
path: "/api/gtest/vtest/rtest/normal_update",
|
||||
obj: getObject("vTest", "rTest", "normal_update"),
|
||||
},
|
||||
{
|
||||
resource: "rtest",
|
||||
name: "namespaced_update",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_update",
|
||||
obj: getObject("gtest/vTest", "rTest", "namespaced_update"),
|
||||
path: "/api/gtest/vtest/namespaces/nstest/rtest/namespaced_update",
|
||||
obj: getObject("vTest", "rTest", "namespaced_update"),
|
||||
},
|
||||
{
|
||||
resource: "rtest",
|
||||
subresource: []string{"srtest"},
|
||||
name: "normal_subresource_update",
|
||||
path: "/apis/gtest/vtest/rtest/normal_update/srtest",
|
||||
obj: getObject("gtest/vTest", "srTest", "normal_update"),
|
||||
resource: "rtest/srtest",
|
||||
name: "normal_subresource_update",
|
||||
path: "/api/gtest/vtest/rtest/normal_update/srtest",
|
||||
obj: getObject("vTest", "srTest", "normal_update"),
|
||||
},
|
||||
{
|
||||
resource: "rtest",
|
||||
subresource: []string{"srtest"},
|
||||
name: "namespaced_subresource_update",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_update/srtest",
|
||||
obj: getObject("gtest/vTest", "srTest", "namespaced_update"),
|
||||
resource: "rtest/srtest",
|
||||
name: "namespaced_subresource_update",
|
||||
namespace: "nstest",
|
||||
path: "/api/gtest/vtest/namespaces/nstest/rtest/namespaced_update/srtest",
|
||||
obj: getObject("vTest", "srTest", "namespaced_update"),
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
resource := schema.GroupVersionResource{Group: "gtest", Version: "vtest", Resource: tc.resource}
|
||||
cl, srv, err := getClientServer(func(w http.ResponseWriter, r *http.Request) {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: tc.resource, Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "PUT" {
|
||||
t.Errorf("Update(%q) got HTTP method %s. wanted PUT", tc.name, r.Method)
|
||||
}
|
||||
@@ -481,7 +457,7 @@ func TestUpdate(t *testing.T) {
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
got, err := cl.Resource(resource).Namespace(tc.namespace).Update(tc.obj, metav1.UpdateOptions{}, tc.subresource...)
|
||||
got, err := cl.Resource(resource, tc.namespace).Update(tc.obj)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when updating %q: %v", tc.name, err)
|
||||
continue
|
||||
@@ -503,29 +479,30 @@ func TestWatch(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "normal_watch",
|
||||
path: "/apis/gtest/vtest/rtest",
|
||||
path: "/api/gtest/vtest/rtest",
|
||||
query: "watch=true",
|
||||
events: []watch.Event{
|
||||
{Type: watch.Added, Object: getObject("gtest/vTest", "rTest", "normal_watch")},
|
||||
{Type: watch.Modified, Object: getObject("gtest/vTest", "rTest", "normal_watch")},
|
||||
{Type: watch.Deleted, Object: getObject("gtest/vTest", "rTest", "normal_watch")},
|
||||
{Type: watch.Added, Object: getObject("vTest", "rTest", "normal_watch")},
|
||||
{Type: watch.Modified, Object: getObject("vTest", "rTest", "normal_watch")},
|
||||
{Type: watch.Deleted, Object: getObject("vTest", "rTest", "normal_watch")},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "namespaced_watch",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest",
|
||||
path: "/api/gtest/vtest/namespaces/nstest/rtest",
|
||||
query: "watch=true",
|
||||
events: []watch.Event{
|
||||
{Type: watch.Added, Object: getObject("gtest/vTest", "rTest", "namespaced_watch")},
|
||||
{Type: watch.Modified, Object: getObject("gtest/vTest", "rTest", "namespaced_watch")},
|
||||
{Type: watch.Deleted, Object: getObject("gtest/vTest", "rTest", "namespaced_watch")},
|
||||
{Type: watch.Added, Object: getObject("vTest", "rTest", "namespaced_watch")},
|
||||
{Type: watch.Modified, Object: getObject("vTest", "rTest", "namespaced_watch")},
|
||||
{Type: watch.Deleted, Object: getObject("vTest", "rTest", "namespaced_watch")},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
resource := schema.GroupVersionResource{Group: "gtest", Version: "vtest", Resource: "rtest"}
|
||||
cl, srv, err := getClientServer(func(w http.ResponseWriter, r *http.Request) {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: "rtest", Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "GET" {
|
||||
t.Errorf("Watch(%q) got HTTP method %s. wanted GET", tc.name, r.Method)
|
||||
}
|
||||
@@ -537,7 +514,7 @@ func TestWatch(t *testing.T) {
|
||||
t.Errorf("Watch(%q) got query %s. wanted %s", tc.name, r.URL.RawQuery, tc.query)
|
||||
}
|
||||
|
||||
enc := restclientwatch.NewEncoder(streaming.NewEncoder(w, unstructured.UnstructuredJSONScheme), unstructured.UnstructuredJSONScheme)
|
||||
enc := restclientwatch.NewEncoder(streaming.NewEncoder(w, dynamicCodec{}), dynamicCodec{})
|
||||
for _, e := range tc.events {
|
||||
enc.Encode(&e)
|
||||
}
|
||||
@@ -548,7 +525,7 @@ func TestWatch(t *testing.T) {
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
watcher, err := cl.Resource(resource).Namespace(tc.namespace).Watch(metav1.ListOptions{})
|
||||
watcher, err := cl.Resource(resource, tc.namespace).Watch(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when watching %q: %v", tc.name, err)
|
||||
continue
|
||||
@@ -565,50 +542,48 @@ func TestWatch(t *testing.T) {
|
||||
|
||||
func TestPatch(t *testing.T) {
|
||||
tcs := []struct {
|
||||
resource string
|
||||
subresource []string
|
||||
name string
|
||||
namespace string
|
||||
patch []byte
|
||||
want *unstructured.Unstructured
|
||||
path string
|
||||
resource string
|
||||
name string
|
||||
namespace string
|
||||
patch []byte
|
||||
want *unstructured.Unstructured
|
||||
path string
|
||||
}{
|
||||
{
|
||||
resource: "rtest",
|
||||
name: "normal_patch",
|
||||
path: "/apis/gtest/vtest/rtest/normal_patch",
|
||||
patch: getJSON("gtest/vTest", "rTest", "normal_patch"),
|
||||
want: getObject("gtest/vTest", "rTest", "normal_patch"),
|
||||
path: "/api/gtest/vtest/rtest/normal_patch",
|
||||
patch: getJSON("vTest", "rTest", "normal_patch"),
|
||||
want: getObject("vTest", "rTest", "normal_patch"),
|
||||
},
|
||||
{
|
||||
resource: "rtest",
|
||||
name: "namespaced_patch",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_patch",
|
||||
patch: getJSON("gtest/vTest", "rTest", "namespaced_patch"),
|
||||
want: getObject("gtest/vTest", "rTest", "namespaced_patch"),
|
||||
path: "/api/gtest/vtest/namespaces/nstest/rtest/namespaced_patch",
|
||||
patch: getJSON("vTest", "rTest", "namespaced_patch"),
|
||||
want: getObject("vTest", "rTest", "namespaced_patch"),
|
||||
},
|
||||
{
|
||||
resource: "rtest",
|
||||
subresource: []string{"srtest"},
|
||||
name: "normal_subresource_patch",
|
||||
path: "/apis/gtest/vtest/rtest/normal_subresource_patch/srtest",
|
||||
patch: getJSON("gtest/vTest", "srTest", "normal_subresource_patch"),
|
||||
want: getObject("gtest/vTest", "srTest", "normal_subresource_patch"),
|
||||
resource: "rtest/srtest",
|
||||
name: "normal_subresource_patch",
|
||||
path: "/api/gtest/vtest/rtest/normal_subresource_patch/srtest",
|
||||
patch: getJSON("vTest", "srTest", "normal_subresource_patch"),
|
||||
want: getObject("vTest", "srTest", "normal_subresource_patch"),
|
||||
},
|
||||
{
|
||||
resource: "rtest",
|
||||
subresource: []string{"srtest"},
|
||||
name: "namespaced_subresource_patch",
|
||||
namespace: "nstest",
|
||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_subresource_patch/srtest",
|
||||
patch: getJSON("gtest/vTest", "srTest", "namespaced_subresource_patch"),
|
||||
want: getObject("gtest/vTest", "srTest", "namespaced_subresource_patch"),
|
||||
resource: "rtest/srtest",
|
||||
name: "namespaced_subresource_patch",
|
||||
namespace: "nstest",
|
||||
path: "/api/gtest/vtest/namespaces/nstest/rtest/namespaced_subresource_patch/srtest",
|
||||
patch: getJSON("vTest", "srTest", "namespaced_subresource_patch"),
|
||||
want: getObject("vTest", "srTest", "namespaced_subresource_patch"),
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
resource := schema.GroupVersionResource{Group: "gtest", Version: "vtest", Resource: tc.resource}
|
||||
cl, srv, err := getClientServer(func(w http.ResponseWriter, r *http.Request) {
|
||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
||||
resource := &metav1.APIResource{Name: tc.resource, Namespaced: len(tc.namespace) != 0}
|
||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "PATCH" {
|
||||
t.Errorf("Patch(%q) got HTTP method %s. wanted PATCH", tc.name, r.Method)
|
||||
}
|
||||
@@ -638,7 +613,7 @@ func TestPatch(t *testing.T) {
|
||||
}
|
||||
defer srv.Close()
|
||||
|
||||
got, err := cl.Resource(resource).Namespace(tc.namespace).Patch(tc.name, types.StrategicMergePatchType, tc.patch, metav1.UpdateOptions{}, tc.subresource...)
|
||||
got, err := cl.Resource(resource, tc.namespace).Patch(tc.name, types.StrategicMergePatchType, tc.patch)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error when patching %q: %v", tc.name, err)
|
||||
continue
|
||||
@@ -649,3 +624,11 @@ func TestPatch(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestVersionedParameterEncoderWithV1Fallback(t *testing.T) {
|
||||
enc := VersionedParameterEncoderWithV1Fallback
|
||||
_, err := enc.EncodeParameters(&metav1.ListOptions{}, schema.GroupVersion{Group: "foo.bar.com", Version: "v4"})
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
96
dynamic/dynamic_util.go
Normal file
96
dynamic/dynamic_util.go
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
Copyright 2016 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 dynamic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// VersionInterfaces provides an object converter and metadata
|
||||
// accessor appropriate for use with unstructured objects.
|
||||
func VersionInterfaces(schema.GroupVersion) (*meta.VersionInterfaces, error) {
|
||||
return &meta.VersionInterfaces{
|
||||
ObjectConvertor: &unstructured.UnstructuredObjectConverter{},
|
||||
MetadataAccessor: meta.NewAccessor(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewDiscoveryRESTMapper returns a RESTMapper based on discovery information.
|
||||
func NewDiscoveryRESTMapper(resources []*metav1.APIResourceList, versionFunc meta.VersionInterfacesFunc) (*meta.DefaultRESTMapper, error) {
|
||||
rm := meta.NewDefaultRESTMapper(nil, versionFunc)
|
||||
for _, resourceList := range resources {
|
||||
gv, err := schema.ParseGroupVersion(resourceList.GroupVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, resource := range resourceList.APIResources {
|
||||
gvk := gv.WithKind(resource.Kind)
|
||||
scope := meta.RESTScopeRoot
|
||||
if resource.Namespaced {
|
||||
scope = meta.RESTScopeNamespace
|
||||
}
|
||||
rm.Add(gvk, scope)
|
||||
}
|
||||
}
|
||||
return rm, nil
|
||||
}
|
||||
|
||||
// ObjectTyper provides an ObjectTyper implementation for
|
||||
// unstructured.Unstructured object based on discovery information.
|
||||
type ObjectTyper struct {
|
||||
registered map[schema.GroupVersionKind]bool
|
||||
}
|
||||
|
||||
// NewObjectTyper constructs an ObjectTyper from discovery information.
|
||||
func NewObjectTyper(resources []*metav1.APIResourceList) (runtime.ObjectTyper, error) {
|
||||
ot := &ObjectTyper{registered: make(map[schema.GroupVersionKind]bool)}
|
||||
for _, resourceList := range resources {
|
||||
gv, err := schema.ParseGroupVersion(resourceList.GroupVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, resource := range resourceList.APIResources {
|
||||
ot.registered[gv.WithKind(resource.Kind)] = true
|
||||
}
|
||||
}
|
||||
return ot, nil
|
||||
}
|
||||
|
||||
// ObjectKinds returns a slice of one element with the
|
||||
// group,version,kind of the provided object, or an error if the
|
||||
// object is not *unstructured.Unstructured or has no group,version,kind
|
||||
// information.
|
||||
func (ot *ObjectTyper) ObjectKinds(obj runtime.Object) ([]schema.GroupVersionKind, bool, error) {
|
||||
if _, ok := obj.(*unstructured.Unstructured); !ok {
|
||||
return nil, false, fmt.Errorf("type %T is invalid for determining dynamic object types", obj)
|
||||
}
|
||||
return []schema.GroupVersionKind{obj.GetObjectKind().GroupVersionKind()}, false, nil
|
||||
}
|
||||
|
||||
// Recognizes returns true if the provided group,version,kind was in
|
||||
// the discovery information.
|
||||
func (ot *ObjectTyper) Recognizes(gvk schema.GroupVersionKind) bool {
|
||||
return ot.registered[gvk]
|
||||
}
|
||||
79
dynamic/dynamic_util_test.go
Normal file
79
dynamic/dynamic_util_test.go
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
Copyright 2016 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 dynamic
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
func TestDiscoveryRESTMapper(t *testing.T) {
|
||||
resources := []*metav1.APIResourceList{
|
||||
{
|
||||
GroupVersion: "test/beta1",
|
||||
APIResources: []metav1.APIResource{
|
||||
{
|
||||
Name: "test_kinds",
|
||||
Namespaced: true,
|
||||
Kind: "test_kind",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
gvk := schema.GroupVersionKind{
|
||||
Group: "test",
|
||||
Version: "beta1",
|
||||
Kind: "test_kind",
|
||||
}
|
||||
|
||||
mapper, err := NewDiscoveryRESTMapper(resources, VersionInterfaces)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error creating mapper: %s", err)
|
||||
}
|
||||
|
||||
for _, res := range []schema.GroupVersionResource{
|
||||
{
|
||||
Group: "test",
|
||||
Version: "beta1",
|
||||
Resource: "test_kinds",
|
||||
},
|
||||
{
|
||||
Version: "beta1",
|
||||
Resource: "test_kinds",
|
||||
},
|
||||
{
|
||||
Group: "test",
|
||||
Resource: "test_kinds",
|
||||
},
|
||||
{
|
||||
Resource: "test_kinds",
|
||||
},
|
||||
} {
|
||||
got, err := mapper.KindFor(res)
|
||||
if err != nil {
|
||||
t.Errorf("KindFor(%#v) unexpected error: %s", res, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if got != gvk {
|
||||
t.Errorf("KindFor(%#v) = %#v; want %#v", res, got, gvk)
|
||||
}
|
||||
}
|
||||
}
|
||||
163
dynamic/fake/client.go
Normal file
163
dynamic/fake/client.go
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
Copyright 2017 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 fake provides a fake client interface to arbitrary Kubernetes
|
||||
// APIs that exposes common high level operations and exposes common
|
||||
// metadata.
|
||||
package fake
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"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/types"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/testing"
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
)
|
||||
|
||||
// FakeClient is a fake implementation of dynamic.Interface.
|
||||
type FakeClient struct {
|
||||
GroupVersion schema.GroupVersion
|
||||
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
// GetRateLimiter returns the rate limiter for this client.
|
||||
func (c *FakeClient) GetRateLimiter() flowcontrol.RateLimiter {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Resource returns an API interface to the specified resource for this client's
|
||||
// group and version. If resource is not a namespaced resource, then namespace
|
||||
// is ignored. The ResourceClient inherits the parameter codec of this client
|
||||
func (c *FakeClient) Resource(resource *metav1.APIResource, namespace string) dynamic.ResourceInterface {
|
||||
return &FakeResourceClient{
|
||||
Resource: c.GroupVersion.WithResource(resource.Name),
|
||||
Kind: c.GroupVersion.WithKind(resource.Kind),
|
||||
Namespace: namespace,
|
||||
|
||||
Fake: c.Fake,
|
||||
}
|
||||
}
|
||||
|
||||
// ParameterCodec returns a client with the provided parameter codec.
|
||||
func (c *FakeClient) ParameterCodec(parameterCodec runtime.ParameterCodec) dynamic.Interface {
|
||||
return &FakeClient{
|
||||
Fake: c.Fake,
|
||||
}
|
||||
}
|
||||
|
||||
// FakeResourceClient is a fake implementation of dynamic.ResourceInterface
|
||||
type FakeResourceClient struct {
|
||||
Resource schema.GroupVersionResource
|
||||
Kind schema.GroupVersionKind
|
||||
Namespace string
|
||||
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
// List returns a list of objects for this resource.
|
||||
func (c *FakeResourceClient) List(opts metav1.ListOptions) (runtime.Object, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(c.Resource, c.Kind, c.Namespace, opts), &unstructured.UnstructuredList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &unstructured.UnstructuredList{}
|
||||
for _, item := range obj.(*unstructured.UnstructuredList).Items {
|
||||
if label.Matches(labels.Set(item.GetLabels())) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Get gets the resource with the specified name.
|
||||
func (c *FakeResourceClient) Get(name string, opts metav1.GetOptions) (*unstructured.Unstructured, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(c.Resource, c.Namespace, name), &unstructured.Unstructured{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return obj.(*unstructured.Unstructured), err
|
||||
}
|
||||
|
||||
// Delete deletes the resource with the specified name.
|
||||
func (c *FakeResourceClient) Delete(name string, opts *metav1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(c.Resource, c.Namespace, name), &unstructured.Unstructured{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeResourceClient) DeleteCollection(deleteOptions *metav1.DeleteOptions, listOptions metav1.ListOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteCollectionAction(c.Resource, c.Namespace, listOptions), &unstructured.Unstructured{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Create creates the provided resource.
|
||||
func (c *FakeResourceClient) Create(inObj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(c.Resource, c.Namespace, inObj), &unstructured.Unstructured{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*unstructured.Unstructured), err
|
||||
}
|
||||
|
||||
// Update updates the provided resource.
|
||||
func (c *FakeResourceClient) Update(inObj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(c.Resource, c.Namespace, inObj), &unstructured.Unstructured{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*unstructured.Unstructured), err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the resource.
|
||||
func (c *FakeResourceClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(c.Resource, c.Namespace, opts))
|
||||
}
|
||||
|
||||
// Patch patches the provided resource.
|
||||
func (c *FakeResourceClient) Patch(name string, pt types.PatchType, data []byte) (*unstructured.Unstructured, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchAction(c.Resource, c.Namespace, name, data), &unstructured.Unstructured{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*unstructured.Unstructured), err
|
||||
}
|
||||
48
dynamic/fake/client_pool.go
Normal file
48
dynamic/fake/client_pool.go
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
Copyright 2017 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 fake provides a fake client interface to arbitrary Kubernetes
|
||||
// APIs that exposes common high level operations and exposes common
|
||||
// metadata.
|
||||
package fake
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakeClientPool provides a fake implementation of dynamic.ClientPool.
|
||||
// It assumes resource GroupVersions are the same as their corresponding kind GroupVersions.
|
||||
type FakeClientPool struct {
|
||||
testing.Fake
|
||||
}
|
||||
|
||||
// ClientForGroupVersionKind returns a client configured for the specified groupVersionResource.
|
||||
// Resource may be empty.
|
||||
func (p *FakeClientPool) ClientForGroupVersionResource(resource schema.GroupVersionResource) (dynamic.Interface, error) {
|
||||
return p.ClientForGroupVersionKind(resource.GroupVersion().WithKind(""))
|
||||
}
|
||||
|
||||
// ClientForGroupVersionKind returns a client configured for the specified groupVersionKind.
|
||||
// Kind may be empty.
|
||||
func (p *FakeClientPool) ClientForGroupVersionKind(kind schema.GroupVersionKind) (dynamic.Interface, error) {
|
||||
// we can just create a new client every time for testing purposes
|
||||
return &FakeClient{
|
||||
GroupVersion: kind.GroupVersion(),
|
||||
Fake: &p.Fake,
|
||||
}, nil
|
||||
}
|
||||
@@ -1,368 +0,0 @@
|
||||
/*
|
||||
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 fake
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"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/runtime/serializer"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
func NewSimpleDynamicClient(scheme *runtime.Scheme, objects ...runtime.Object) *FakeDynamicClient {
|
||||
// In order to use List with this client, you have to have the v1.List registered in your scheme. Neat thing though
|
||||
// it does NOT have to be the *same* list
|
||||
scheme.AddKnownTypeWithName(schema.GroupVersionKind{Group: "fake-dynamic-client-group", Version: "v1", Kind: "List"}, &unstructured.UnstructuredList{})
|
||||
|
||||
codecs := serializer.NewCodecFactory(scheme)
|
||||
o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder())
|
||||
for _, obj := range objects {
|
||||
if err := o.Add(obj); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
cs := &FakeDynamicClient{}
|
||||
cs.AddReactor("*", "*", testing.ObjectReaction(o))
|
||||
cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) {
|
||||
gvr := action.GetResource()
|
||||
ns := action.GetNamespace()
|
||||
watch, err := o.Watch(gvr, ns)
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
return true, watch, nil
|
||||
})
|
||||
|
||||
return cs
|
||||
}
|
||||
|
||||
// Clientset implements clientset.Interface. Meant to be embedded into a
|
||||
// struct to get a default implementation. This makes faking out just the method
|
||||
// you want to test easier.
|
||||
type FakeDynamicClient struct {
|
||||
testing.Fake
|
||||
scheme *runtime.Scheme
|
||||
}
|
||||
|
||||
type dynamicResourceClient struct {
|
||||
client *FakeDynamicClient
|
||||
namespace string
|
||||
resource schema.GroupVersionResource
|
||||
}
|
||||
|
||||
var _ dynamic.Interface = &FakeDynamicClient{}
|
||||
|
||||
func (c *FakeDynamicClient) Resource(resource schema.GroupVersionResource) dynamic.NamespaceableResourceInterface {
|
||||
return &dynamicResourceClient{client: c, resource: resource}
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) Namespace(ns string) dynamic.ResourceInterface {
|
||||
ret := *c
|
||||
ret.namespace = ns
|
||||
return &ret
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) Create(obj *unstructured.Unstructured, opts metav1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) {
|
||||
var uncastRet runtime.Object
|
||||
var err error
|
||||
switch {
|
||||
case len(c.namespace) == 0 && len(subresources) == 0:
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewRootCreateAction(c.resource, obj), obj)
|
||||
|
||||
case len(c.namespace) == 0 && len(subresources) > 0:
|
||||
accessor, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
name := accessor.GetName()
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewRootCreateSubresourceAction(c.resource, name, strings.Join(subresources, "/"), obj), obj)
|
||||
|
||||
case len(c.namespace) > 0 && len(subresources) == 0:
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewCreateAction(c.resource, c.namespace, obj), obj)
|
||||
|
||||
case len(c.namespace) > 0 && len(subresources) > 0:
|
||||
accessor, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
name := accessor.GetName()
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewCreateSubresourceAction(c.resource, name, strings.Join(subresources, "/"), c.namespace, obj), obj)
|
||||
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if uncastRet == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret := &unstructured.Unstructured{}
|
||||
if err := c.client.scheme.Convert(uncastRet, ret, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) Update(obj *unstructured.Unstructured, opts metav1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) {
|
||||
var uncastRet runtime.Object
|
||||
var err error
|
||||
switch {
|
||||
case len(c.namespace) == 0 && len(subresources) == 0:
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewRootUpdateAction(c.resource, obj), obj)
|
||||
|
||||
case len(c.namespace) == 0 && len(subresources) > 0:
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewRootUpdateSubresourceAction(c.resource, strings.Join(subresources, "/"), obj), obj)
|
||||
|
||||
case len(c.namespace) > 0 && len(subresources) == 0:
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewUpdateAction(c.resource, c.namespace, obj), obj)
|
||||
|
||||
case len(c.namespace) > 0 && len(subresources) > 0:
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(c.resource, strings.Join(subresources, "/"), c.namespace, obj), obj)
|
||||
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if uncastRet == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret := &unstructured.Unstructured{}
|
||||
if err := c.client.scheme.Convert(uncastRet, ret, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) UpdateStatus(obj *unstructured.Unstructured, opts metav1.UpdateOptions) (*unstructured.Unstructured, error) {
|
||||
var uncastRet runtime.Object
|
||||
var err error
|
||||
switch {
|
||||
case len(c.namespace) == 0:
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewRootUpdateSubresourceAction(c.resource, "status", obj), obj)
|
||||
|
||||
case len(c.namespace) > 0:
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(c.resource, "status", c.namespace, obj), obj)
|
||||
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if uncastRet == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret := &unstructured.Unstructured{}
|
||||
if err := c.client.scheme.Convert(uncastRet, ret, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) Delete(name string, opts *metav1.DeleteOptions, subresources ...string) error {
|
||||
var err error
|
||||
switch {
|
||||
case len(c.namespace) == 0 && len(subresources) == 0:
|
||||
_, err = c.client.Fake.
|
||||
Invokes(testing.NewRootDeleteAction(c.resource, name), &metav1.Status{Status: "dynamic delete fail"})
|
||||
|
||||
case len(c.namespace) == 0 && len(subresources) > 0:
|
||||
_, err = c.client.Fake.
|
||||
Invokes(testing.NewRootDeleteSubresourceAction(c.resource, strings.Join(subresources, "/"), name), &metav1.Status{Status: "dynamic delete fail"})
|
||||
|
||||
case len(c.namespace) > 0 && len(subresources) == 0:
|
||||
_, err = c.client.Fake.
|
||||
Invokes(testing.NewDeleteAction(c.resource, c.namespace, name), &metav1.Status{Status: "dynamic delete fail"})
|
||||
|
||||
case len(c.namespace) > 0 && len(subresources) > 0:
|
||||
_, err = c.client.Fake.
|
||||
Invokes(testing.NewDeleteSubresourceAction(c.resource, strings.Join(subresources, "/"), c.namespace, name), &metav1.Status{Status: "dynamic delete fail"})
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) DeleteCollection(opts *metav1.DeleteOptions, listOptions metav1.ListOptions) error {
|
||||
var err error
|
||||
switch {
|
||||
case len(c.namespace) == 0:
|
||||
action := testing.NewRootDeleteCollectionAction(c.resource, listOptions)
|
||||
_, err = c.client.Fake.Invokes(action, &metav1.Status{Status: "dynamic deletecollection fail"})
|
||||
|
||||
case len(c.namespace) > 0:
|
||||
action := testing.NewDeleteCollectionAction(c.resource, c.namespace, listOptions)
|
||||
_, err = c.client.Fake.Invokes(action, &metav1.Status{Status: "dynamic deletecollection fail"})
|
||||
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) Get(name string, opts metav1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) {
|
||||
var uncastRet runtime.Object
|
||||
var err error
|
||||
switch {
|
||||
case len(c.namespace) == 0 && len(subresources) == 0:
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewRootGetAction(c.resource, name), &metav1.Status{Status: "dynamic get fail"})
|
||||
|
||||
case len(c.namespace) == 0 && len(subresources) > 0:
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewRootGetSubresourceAction(c.resource, strings.Join(subresources, "/"), name), &metav1.Status{Status: "dynamic get fail"})
|
||||
|
||||
case len(c.namespace) > 0 && len(subresources) == 0:
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewGetAction(c.resource, c.namespace, name), &metav1.Status{Status: "dynamic get fail"})
|
||||
|
||||
case len(c.namespace) > 0 && len(subresources) > 0:
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewGetSubresourceAction(c.resource, c.namespace, strings.Join(subresources, "/"), name), &metav1.Status{Status: "dynamic get fail"})
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if uncastRet == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret := &unstructured.Unstructured{}
|
||||
if err := c.client.scheme.Convert(uncastRet, ret, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) List(opts metav1.ListOptions) (*unstructured.UnstructuredList, error) {
|
||||
var obj runtime.Object
|
||||
var err error
|
||||
switch {
|
||||
case len(c.namespace) == 0:
|
||||
obj, err = c.client.Fake.
|
||||
Invokes(testing.NewRootListAction(c.resource, schema.GroupVersionKind{Group: "fake-dynamic-client-group", Version: "v1", Kind: "" /*List is appended by the tracker automatically*/}, opts), &metav1.Status{Status: "dynamic list fail"})
|
||||
|
||||
case len(c.namespace) > 0:
|
||||
obj, err = c.client.Fake.
|
||||
Invokes(testing.NewListAction(c.resource, schema.GroupVersionKind{Group: "fake-dynamic-client-group", Version: "v1", Kind: "" /*List is appended by the tracker automatically*/}, c.namespace, opts), &metav1.Status{Status: "dynamic list fail"})
|
||||
|
||||
}
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
|
||||
retUnstructured := &unstructured.Unstructured{}
|
||||
if err := c.client.scheme.Convert(obj, retUnstructured, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entireList, err := retUnstructured.ToList()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list := &unstructured.UnstructuredList{}
|
||||
for i := range entireList.Items {
|
||||
item := &entireList.Items[i]
|
||||
metadata, err := meta.Accessor(item)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if label.Matches(labels.Set(metadata.GetLabels())) {
|
||||
list.Items = append(list.Items, *item)
|
||||
}
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
switch {
|
||||
case len(c.namespace) == 0:
|
||||
return c.client.Fake.
|
||||
InvokesWatch(testing.NewRootWatchAction(c.resource, opts))
|
||||
|
||||
case len(c.namespace) > 0:
|
||||
return c.client.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(c.resource, c.namespace, opts))
|
||||
|
||||
}
|
||||
|
||||
panic("math broke")
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) Patch(name string, pt types.PatchType, data []byte, opts metav1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) {
|
||||
var uncastRet runtime.Object
|
||||
var err error
|
||||
switch {
|
||||
case len(c.namespace) == 0 && len(subresources) == 0:
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewRootPatchAction(c.resource, name, data), &metav1.Status{Status: "dynamic patch fail"})
|
||||
|
||||
case len(c.namespace) == 0 && len(subresources) > 0:
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(c.resource, name, data, subresources...), &metav1.Status{Status: "dynamic patch fail"})
|
||||
|
||||
case len(c.namespace) > 0 && len(subresources) == 0:
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewPatchAction(c.resource, c.namespace, name, data), &metav1.Status{Status: "dynamic patch fail"})
|
||||
|
||||
case len(c.namespace) > 0 && len(subresources) > 0:
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(c.resource, c.namespace, name, data, subresources...), &metav1.Status{Status: "dynamic patch fail"})
|
||||
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if uncastRet == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret := &unstructured.Unstructured{}
|
||||
if err := c.client.scheme.Convert(uncastRet, ret, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, err
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
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 fake
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/equality"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
)
|
||||
|
||||
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 TestList(t *testing.T) {
|
||||
scheme := runtime.NewScheme()
|
||||
|
||||
client := NewSimpleDynamicClient(scheme,
|
||||
newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"),
|
||||
newUnstructured("group2/version", "TheKind", "ns-foo", "name2-foo"),
|
||||
newUnstructured("group/version", "TheKind", "ns-foo", "name-bar"),
|
||||
newUnstructured("group/version", "TheKind", "ns-foo", "name-baz"),
|
||||
newUnstructured("group2/version", "TheKind", "ns-foo", "name2-baz"),
|
||||
)
|
||||
listFirst, err := client.Resource(schema.GroupVersionResource{Group: "group", Version: "version", Resource: "thekinds"}).List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
expected := []unstructured.Unstructured{
|
||||
*newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"),
|
||||
*newUnstructured("group/version", "TheKind", "ns-foo", "name-bar"),
|
||||
*newUnstructured("group/version", "TheKind", "ns-foo", "name-baz"),
|
||||
}
|
||||
if !equality.Semantic.DeepEqual(listFirst.Items, expected) {
|
||||
t.Fatal(diff.ObjectGoPrintDiff(expected, listFirst.Items))
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 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 dynamic
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
Resource(resource schema.GroupVersionResource) NamespaceableResourceInterface
|
||||
}
|
||||
|
||||
type ResourceInterface interface {
|
||||
Create(obj *unstructured.Unstructured, options metav1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error)
|
||||
Update(obj *unstructured.Unstructured, options metav1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error)
|
||||
UpdateStatus(obj *unstructured.Unstructured, options metav1.UpdateOptions) (*unstructured.Unstructured, error)
|
||||
Delete(name string, options *metav1.DeleteOptions, subresources ...string) error
|
||||
DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error
|
||||
Get(name string, options metav1.GetOptions, subresources ...string) (*unstructured.Unstructured, error)
|
||||
List(opts metav1.ListOptions) (*unstructured.UnstructuredList, error)
|
||||
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, options metav1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error)
|
||||
}
|
||||
|
||||
type NamespaceableResourceInterface interface {
|
||||
Namespace(string) ResourceInterface
|
||||
ResourceInterface
|
||||
}
|
||||
|
||||
// APIPathResolverFunc knows how to convert a groupVersion to its API path. The Kind field is optional.
|
||||
// TODO find a better place to move this for existing callers
|
||||
type APIPathResolverFunc func(kind schema.GroupVersionKind) string
|
||||
|
||||
// LegacyAPIPathResolverFunc can resolve paths properly with the legacy API.
|
||||
// TODO find a better place to move this for existing callers
|
||||
func LegacyAPIPathResolverFunc(kind schema.GroupVersionKind) string {
|
||||
if len(kind.Group) == 0 {
|
||||
return "/api"
|
||||
}
|
||||
return "/apis"
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
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 dynamic
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/versioning"
|
||||
)
|
||||
|
||||
var watchScheme = runtime.NewScheme()
|
||||
var basicScheme = runtime.NewScheme()
|
||||
var deleteScheme = runtime.NewScheme()
|
||||
var parameterScheme = runtime.NewScheme()
|
||||
var deleteOptionsCodec = serializer.NewCodecFactory(deleteScheme)
|
||||
var dynamicParameterCodec = runtime.NewParameterCodec(parameterScheme)
|
||||
|
||||
var versionV1 = schema.GroupVersion{Version: "v1"}
|
||||
|
||||
func init() {
|
||||
metav1.AddToGroupVersion(watchScheme, versionV1)
|
||||
metav1.AddToGroupVersion(basicScheme, versionV1)
|
||||
metav1.AddToGroupVersion(parameterScheme, versionV1)
|
||||
metav1.AddToGroupVersion(deleteScheme, versionV1)
|
||||
}
|
||||
|
||||
var watchJsonSerializerInfo = runtime.SerializerInfo{
|
||||
MediaType: "application/json",
|
||||
EncodesAsText: true,
|
||||
Serializer: json.NewSerializer(json.DefaultMetaFactory, watchScheme, watchScheme, false),
|
||||
PrettySerializer: json.NewSerializer(json.DefaultMetaFactory, watchScheme, watchScheme, true),
|
||||
StreamSerializer: &runtime.StreamSerializerInfo{
|
||||
EncodesAsText: true,
|
||||
Serializer: json.NewSerializer(json.DefaultMetaFactory, watchScheme, watchScheme, false),
|
||||
Framer: json.Framer,
|
||||
},
|
||||
}
|
||||
|
||||
// watchNegotiatedSerializer is used to read the wrapper of the watch stream
|
||||
type watchNegotiatedSerializer struct{}
|
||||
|
||||
var watchNegotiatedSerializerInstance = watchNegotiatedSerializer{}
|
||||
|
||||
func (s watchNegotiatedSerializer) SupportedMediaTypes() []runtime.SerializerInfo {
|
||||
return []runtime.SerializerInfo{watchJsonSerializerInfo}
|
||||
}
|
||||
|
||||
func (s watchNegotiatedSerializer) EncoderForVersion(encoder runtime.Encoder, gv runtime.GroupVersioner) runtime.Encoder {
|
||||
return versioning.NewDefaultingCodecForScheme(watchScheme, encoder, nil, gv, nil)
|
||||
}
|
||||
|
||||
func (s watchNegotiatedSerializer) DecoderToVersion(decoder runtime.Decoder, gv runtime.GroupVersioner) runtime.Decoder {
|
||||
return versioning.NewDefaultingCodecForScheme(watchScheme, nil, decoder, nil, gv)
|
||||
}
|
||||
|
||||
// basicNegotiatedSerializer is used to handle discovery and error handling serialization
|
||||
type basicNegotiatedSerializer struct{}
|
||||
|
||||
func (s basicNegotiatedSerializer) SupportedMediaTypes() []runtime.SerializerInfo {
|
||||
return []runtime.SerializerInfo{
|
||||
{
|
||||
MediaType: "application/json",
|
||||
EncodesAsText: true,
|
||||
Serializer: json.NewSerializer(json.DefaultMetaFactory, basicScheme, basicScheme, false),
|
||||
PrettySerializer: json.NewSerializer(json.DefaultMetaFactory, basicScheme, basicScheme, true),
|
||||
StreamSerializer: &runtime.StreamSerializerInfo{
|
||||
EncodesAsText: true,
|
||||
Serializer: json.NewSerializer(json.DefaultMetaFactory, basicScheme, basicScheme, false),
|
||||
Framer: json.Framer,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (s basicNegotiatedSerializer) EncoderForVersion(encoder runtime.Encoder, gv runtime.GroupVersioner) runtime.Encoder {
|
||||
return versioning.NewDefaultingCodecForScheme(watchScheme, encoder, nil, gv, nil)
|
||||
}
|
||||
|
||||
func (s basicNegotiatedSerializer) DecoderToVersion(decoder runtime.Decoder, gv runtime.GroupVersioner) runtime.Decoder {
|
||||
return versioning.NewDefaultingCodecForScheme(watchScheme, nil, decoder, nil, gv)
|
||||
}
|
||||
@@ -1,326 +0,0 @@
|
||||
/*
|
||||
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 dynamic
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/streaming"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type dynamicClient struct {
|
||||
client *rest.RESTClient
|
||||
}
|
||||
|
||||
var _ Interface = &dynamicClient{}
|
||||
|
||||
// NewForConfigOrDie creates a new Interface for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) Interface {
|
||||
ret, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func NewForConfig(inConfig *rest.Config) (Interface, error) {
|
||||
config := rest.CopyConfig(inConfig)
|
||||
// for serializing the options
|
||||
config.GroupVersion = &schema.GroupVersion{}
|
||||
config.APIPath = "/if-you-see-this-search-for-the-break"
|
||||
config.AcceptContentTypes = "application/json"
|
||||
config.ContentType = "application/json"
|
||||
config.NegotiatedSerializer = basicNegotiatedSerializer{} // this gets used for discovery and error handling types
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
restClient, err := rest.RESTClientFor(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &dynamicClient{client: restClient}, nil
|
||||
}
|
||||
|
||||
type dynamicResourceClient struct {
|
||||
client *dynamicClient
|
||||
namespace string
|
||||
resource schema.GroupVersionResource
|
||||
}
|
||||
|
||||
func (c *dynamicClient) Resource(resource schema.GroupVersionResource) NamespaceableResourceInterface {
|
||||
return &dynamicResourceClient{client: c, resource: resource}
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) Namespace(ns string) ResourceInterface {
|
||||
ret := *c
|
||||
ret.namespace = ns
|
||||
return &ret
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) Create(obj *unstructured.Unstructured, opts metav1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) {
|
||||
outBytes, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
name := ""
|
||||
if len(subresources) > 0 {
|
||||
accessor, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
name = accessor.GetName()
|
||||
}
|
||||
|
||||
result := c.client.client.
|
||||
Post().
|
||||
AbsPath(append(c.makeURLSegments(name), subresources...)...).
|
||||
Body(outBytes).
|
||||
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
||||
Do()
|
||||
if err := result.Error(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
retBytes, err := result.Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uncastObj, err := runtime.Decode(unstructured.UnstructuredJSONScheme, retBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return uncastObj.(*unstructured.Unstructured), nil
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) Update(obj *unstructured.Unstructured, opts metav1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) {
|
||||
accessor, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
outBytes, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := c.client.client.
|
||||
Put().
|
||||
AbsPath(append(c.makeURLSegments(accessor.GetName()), subresources...)...).
|
||||
Body(outBytes).
|
||||
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
||||
Do()
|
||||
if err := result.Error(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
retBytes, err := result.Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uncastObj, err := runtime.Decode(unstructured.UnstructuredJSONScheme, retBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return uncastObj.(*unstructured.Unstructured), nil
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) UpdateStatus(obj *unstructured.Unstructured, opts metav1.UpdateOptions) (*unstructured.Unstructured, error) {
|
||||
accessor, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
outBytes, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := c.client.client.
|
||||
Put().
|
||||
AbsPath(append(c.makeURLSegments(accessor.GetName()), "status")...).
|
||||
Body(outBytes).
|
||||
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
||||
Do()
|
||||
if err := result.Error(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
retBytes, err := result.Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uncastObj, err := runtime.Decode(unstructured.UnstructuredJSONScheme, retBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return uncastObj.(*unstructured.Unstructured), nil
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) Delete(name string, opts *metav1.DeleteOptions, subresources ...string) error {
|
||||
if opts == nil {
|
||||
opts = &metav1.DeleteOptions{}
|
||||
}
|
||||
deleteOptionsByte, err := runtime.Encode(deleteOptionsCodec.LegacyCodec(schema.GroupVersion{Version: "v1"}), opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
result := c.client.client.
|
||||
Delete().
|
||||
AbsPath(append(c.makeURLSegments(name), subresources...)...).
|
||||
Body(deleteOptionsByte).
|
||||
Do()
|
||||
return result.Error()
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) DeleteCollection(opts *metav1.DeleteOptions, listOptions metav1.ListOptions) error {
|
||||
if opts == nil {
|
||||
opts = &metav1.DeleteOptions{}
|
||||
}
|
||||
deleteOptionsByte, err := runtime.Encode(deleteOptionsCodec.LegacyCodec(schema.GroupVersion{Version: "v1"}), opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
result := c.client.client.
|
||||
Delete().
|
||||
AbsPath(c.makeURLSegments("")...).
|
||||
Body(deleteOptionsByte).
|
||||
SpecificallyVersionedParams(&listOptions, dynamicParameterCodec, versionV1).
|
||||
Do()
|
||||
return result.Error()
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) Get(name string, opts metav1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) {
|
||||
result := c.client.client.Get().AbsPath(append(c.makeURLSegments(name), subresources...)...).SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).Do()
|
||||
if err := result.Error(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
retBytes, err := result.Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uncastObj, err := runtime.Decode(unstructured.UnstructuredJSONScheme, retBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return uncastObj.(*unstructured.Unstructured), nil
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) List(opts metav1.ListOptions) (*unstructured.UnstructuredList, error) {
|
||||
result := c.client.client.Get().AbsPath(c.makeURLSegments("")...).SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).Do()
|
||||
if err := result.Error(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
retBytes, err := result.Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uncastObj, err := runtime.Decode(unstructured.UnstructuredJSONScheme, retBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if list, ok := uncastObj.(*unstructured.UnstructuredList); ok {
|
||||
return list, nil
|
||||
}
|
||||
|
||||
list, err := uncastObj.(*unstructured.Unstructured).ToList()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||
internalGV := schema.GroupVersions{
|
||||
{Group: c.resource.Group, Version: runtime.APIVersionInternal},
|
||||
// always include the legacy group as a decoding target to handle non-error `Status` return types
|
||||
{Group: "", Version: runtime.APIVersionInternal},
|
||||
}
|
||||
s := &rest.Serializers{
|
||||
Encoder: watchNegotiatedSerializerInstance.EncoderForVersion(watchJsonSerializerInfo.Serializer, c.resource.GroupVersion()),
|
||||
Decoder: watchNegotiatedSerializerInstance.DecoderToVersion(watchJsonSerializerInfo.Serializer, internalGV),
|
||||
|
||||
RenegotiatedDecoder: func(contentType string, params map[string]string) (runtime.Decoder, error) {
|
||||
return watchNegotiatedSerializerInstance.DecoderToVersion(watchJsonSerializerInfo.Serializer, internalGV), nil
|
||||
},
|
||||
StreamingSerializer: watchJsonSerializerInfo.StreamSerializer.Serializer,
|
||||
Framer: watchJsonSerializerInfo.StreamSerializer.Framer,
|
||||
}
|
||||
|
||||
wrappedDecoderFn := func(body io.ReadCloser) streaming.Decoder {
|
||||
framer := s.Framer.NewFrameReader(body)
|
||||
return streaming.NewDecoder(framer, s.StreamingSerializer)
|
||||
}
|
||||
|
||||
opts.Watch = true
|
||||
return c.client.client.Get().AbsPath(c.makeURLSegments("")...).
|
||||
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
||||
WatchWithSpecificDecoders(wrappedDecoderFn, unstructured.UnstructuredJSONScheme)
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) Patch(name string, pt types.PatchType, data []byte, opts metav1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) {
|
||||
result := c.client.client.
|
||||
Patch(pt).
|
||||
AbsPath(append(c.makeURLSegments(name), subresources...)...).
|
||||
Body(data).
|
||||
SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).
|
||||
Do()
|
||||
if err := result.Error(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
retBytes, err := result.Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uncastObj, err := runtime.Decode(unstructured.UnstructuredJSONScheme, retBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return uncastObj.(*unstructured.Unstructured), nil
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) makeURLSegments(name string) []string {
|
||||
url := []string{}
|
||||
if len(c.resource.Group) == 0 {
|
||||
url = append(url, "api")
|
||||
} else {
|
||||
url = append(url, "apis", c.resource.Group)
|
||||
}
|
||||
url = append(url, c.resource.Version)
|
||||
|
||||
if len(c.namespace) > 0 {
|
||||
url = append(url, "namespaces", c.namespace)
|
||||
}
|
||||
url = append(url, c.resource.Resource)
|
||||
|
||||
if len(name) > 0 {
|
||||
url = append(url, name)
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
@@ -25,7 +25,3 @@ for client-go.
|
||||
the custom resources.
|
||||
|
||||
[informer]: https://godoc.org/k8s.io/client-go/tools/cache#NewInformer
|
||||
|
||||
### Testing
|
||||
|
||||
- [**Fake Client**](./fake-client): Use a fake client in tests.
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
@@ -53,19 +53,14 @@ func main() {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
deploymentsClient := clientset.AppsV1().Deployments(apiv1.NamespaceDefault)
|
||||
deploymentsClient := clientset.AppsV1beta1().Deployments(apiv1.NamespaceDefault)
|
||||
|
||||
deployment := &appsv1.Deployment{
|
||||
deployment := &appsv1beta1.Deployment{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "demo-deployment",
|
||||
},
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
Spec: appsv1beta1.DeploymentSpec{
|
||||
Replicas: int32Ptr(2),
|
||||
Selector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
"app": "demo",
|
||||
},
|
||||
},
|
||||
Template: apiv1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
@@ -133,6 +128,27 @@ func main() {
|
||||
}
|
||||
fmt.Println("Updated deployment...")
|
||||
|
||||
// Rollback Deployment
|
||||
prompt()
|
||||
fmt.Println("Rolling back deployment...")
|
||||
// Once again use RetryOnConflict to avoid update conflicts
|
||||
retryErr = retry.RetryOnConflict(retry.DefaultRetry, func() error {
|
||||
result, getErr := deploymentsClient.Get("demo-deployment", metav1.GetOptions{})
|
||||
if getErr != nil {
|
||||
panic(fmt.Errorf("Failed to get latest version of Deployment: %v", getErr))
|
||||
}
|
||||
|
||||
result.Spec.RollbackTo = &appsv1beta1.RollbackConfig{
|
||||
Revision: 0, // can be specific revision number, or 0 for last revision
|
||||
}
|
||||
_, updateErr := deploymentsClient.Update(result)
|
||||
return updateErr
|
||||
})
|
||||
if retryErr != nil {
|
||||
panic(fmt.Errorf("Rollback failed: %v", retryErr))
|
||||
}
|
||||
fmt.Println("Rolled back deployment...")
|
||||
|
||||
// List Deployments
|
||||
prompt()
|
||||
fmt.Printf("Listing deployments in namespace %q:\n", apiv1.NamespaceDefault)
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
# Fake Client Example
|
||||
|
||||
This example demonstrates how to use a fake client with SharedInformerFactory in tests.
|
||||
|
||||
It covers:
|
||||
* Creating the fake client
|
||||
* Setting up real informers
|
||||
* Injecting events into those informers
|
||||
|
||||
## Running
|
||||
|
||||
```
|
||||
go test -v k8s.io/client-go/examples/fake-client
|
||||
```
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
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 fakeclient contains examples on how to use fakeclient in tests.
|
||||
// Note: This file is here to avoid warnings on go build since there are no
|
||||
// non-test files in this package.
|
||||
package fakeclient
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
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 fakeclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// TestFakeClient demonstrates how to use a fake client with SharedInformerFactory in tests.
|
||||
func TestFakeClient(t *testing.T) {
|
||||
// Use a timeout to keep the test from hanging.
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
|
||||
// Create the fake client.
|
||||
client := fake.NewSimpleClientset()
|
||||
|
||||
// We will create an informer that writes added pods to a channel.
|
||||
pods := make(chan *v1.Pod, 1)
|
||||
informers := informers.NewSharedInformerFactory(client, 0)
|
||||
podInformer := informers.Core().V1().Pods().Informer()
|
||||
podInformer.AddEventHandler(&cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {
|
||||
pod := obj.(*v1.Pod)
|
||||
t.Logf("pod added: %s/%s", pod.Namespace, pod.Name)
|
||||
pods <- pod
|
||||
cancel()
|
||||
},
|
||||
})
|
||||
|
||||
// Make sure informers are running.
|
||||
informers.Start(ctx.Done())
|
||||
|
||||
// This is not required in tests, but it serves as a proof-of-concept by
|
||||
// ensuring that the informer goroutine have warmed up and called List before
|
||||
// we send any events to it.
|
||||
for !podInformer.HasSynced() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
|
||||
// Inject an event into the fake client.
|
||||
p := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "my-pod"}}
|
||||
_, err := client.Core().Pods("test-ns").Create(p)
|
||||
if err != nil {
|
||||
t.Errorf("error injecting pod add: %v", err)
|
||||
}
|
||||
|
||||
// Wait and check result.
|
||||
<-ctx.Done()
|
||||
select {
|
||||
case pod := <-pods:
|
||||
t.Logf("Got pod from channel: %s/%s", pod.Namespace, pod.Name)
|
||||
default:
|
||||
t.Error("Informer did not get the added pod")
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,7 +21,7 @@ package v1alpha1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1"
|
||||
admissionregistration_v1alpha1 "k8s.io/api/admissionregistration/v1alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
@@ -69,7 +69,7 @@ func NewFilteredInitializerConfigurationInformer(client kubernetes.Interface, re
|
||||
return client.AdmissionregistrationV1alpha1().InitializerConfigurations().Watch(options)
|
||||
},
|
||||
},
|
||||
&admissionregistrationv1alpha1.InitializerConfiguration{},
|
||||
&admissionregistration_v1alpha1.InitializerConfiguration{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -80,7 +80,7 @@ func (f *initializerConfigurationInformer) defaultInformer(client kubernetes.Int
|
||||
}
|
||||
|
||||
func (f *initializerConfigurationInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&admissionregistrationv1alpha1.InitializerConfiguration{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&admissionregistration_v1alpha1.InitializerConfiguration{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *initializerConfigurationInformer) Lister() v1alpha1.InitializerConfigurationLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,7 +21,7 @@ package v1beta1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
|
||||
admissionregistration_v1beta1 "k8s.io/api/admissionregistration/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
@@ -69,7 +69,7 @@ func NewFilteredMutatingWebhookConfigurationInformer(client kubernetes.Interface
|
||||
return client.AdmissionregistrationV1beta1().MutatingWebhookConfigurations().Watch(options)
|
||||
},
|
||||
},
|
||||
&admissionregistrationv1beta1.MutatingWebhookConfiguration{},
|
||||
&admissionregistration_v1beta1.MutatingWebhookConfiguration{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -80,7 +80,7 @@ func (f *mutatingWebhookConfigurationInformer) defaultInformer(client kubernetes
|
||||
}
|
||||
|
||||
func (f *mutatingWebhookConfigurationInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&admissionregistrationv1beta1.MutatingWebhookConfiguration{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&admissionregistration_v1beta1.MutatingWebhookConfiguration{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *mutatingWebhookConfigurationInformer) Lister() v1beta1.MutatingWebhookConfigurationLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,7 +21,7 @@ package v1beta1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
|
||||
admissionregistration_v1beta1 "k8s.io/api/admissionregistration/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
@@ -69,7 +69,7 @@ func NewFilteredValidatingWebhookConfigurationInformer(client kubernetes.Interfa
|
||||
return client.AdmissionregistrationV1beta1().ValidatingWebhookConfigurations().Watch(options)
|
||||
},
|
||||
},
|
||||
&admissionregistrationv1beta1.ValidatingWebhookConfiguration{},
|
||||
&admissionregistration_v1beta1.ValidatingWebhookConfiguration{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -80,7 +80,7 @@ func (f *validatingWebhookConfigurationInformer) defaultInformer(client kubernet
|
||||
}
|
||||
|
||||
func (f *validatingWebhookConfigurationInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&admissionregistrationv1beta1.ValidatingWebhookConfiguration{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&admissionregistration_v1beta1.ValidatingWebhookConfiguration{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *validatingWebhookConfigurationInformer) Lister() v1beta1.ValidatingWebhookConfigurationLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
apps_v1 "k8s.io/api/apps/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -57,20 +57,20 @@ func NewControllerRevisionInformer(client kubernetes.Interface, namespace string
|
||||
func NewFilteredControllerRevisionInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.AppsV1().ControllerRevisions(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.AppsV1().ControllerRevisions(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&appsv1.ControllerRevision{},
|
||||
&apps_v1.ControllerRevision{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *controllerRevisionInformer) defaultInformer(client kubernetes.Interface
|
||||
}
|
||||
|
||||
func (f *controllerRevisionInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&appsv1.ControllerRevision{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&apps_v1.ControllerRevision{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *controllerRevisionInformer) Lister() v1.ControllerRevisionLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
apps_v1 "k8s.io/api/apps/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -57,20 +57,20 @@ func NewDaemonSetInformer(client kubernetes.Interface, namespace string, resyncP
|
||||
func NewFilteredDaemonSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.AppsV1().DaemonSets(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.AppsV1().DaemonSets(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&appsv1.DaemonSet{},
|
||||
&apps_v1.DaemonSet{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *daemonSetInformer) defaultInformer(client kubernetes.Interface, resyncP
|
||||
}
|
||||
|
||||
func (f *daemonSetInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&appsv1.DaemonSet{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&apps_v1.DaemonSet{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *daemonSetInformer) Lister() v1.DaemonSetLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
apps_v1 "k8s.io/api/apps/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -57,20 +57,20 @@ func NewDeploymentInformer(client kubernetes.Interface, namespace string, resync
|
||||
func NewFilteredDeploymentInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.AppsV1().Deployments(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.AppsV1().Deployments(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&appsv1.Deployment{},
|
||||
&apps_v1.Deployment{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *deploymentInformer) defaultInformer(client kubernetes.Interface, resync
|
||||
}
|
||||
|
||||
func (f *deploymentInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&appsv1.Deployment{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&apps_v1.Deployment{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *deploymentInformer) Lister() v1.DeploymentLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
apps_v1 "k8s.io/api/apps/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -57,20 +57,20 @@ func NewReplicaSetInformer(client kubernetes.Interface, namespace string, resync
|
||||
func NewFilteredReplicaSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.AppsV1().ReplicaSets(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.AppsV1().ReplicaSets(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&appsv1.ReplicaSet{},
|
||||
&apps_v1.ReplicaSet{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *replicaSetInformer) defaultInformer(client kubernetes.Interface, resync
|
||||
}
|
||||
|
||||
func (f *replicaSetInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&appsv1.ReplicaSet{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&apps_v1.ReplicaSet{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *replicaSetInformer) Lister() v1.ReplicaSetLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
apps_v1 "k8s.io/api/apps/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -57,20 +57,20 @@ func NewStatefulSetInformer(client kubernetes.Interface, namespace string, resyn
|
||||
func NewFilteredStatefulSetInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.AppsV1().StatefulSets(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.AppsV1().StatefulSets(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&appsv1.StatefulSet{},
|
||||
&apps_v1.StatefulSet{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *statefulSetInformer) defaultInformer(client kubernetes.Interface, resyn
|
||||
}
|
||||
|
||||
func (f *statefulSetInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&appsv1.StatefulSet{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&apps_v1.StatefulSet{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *statefulSetInformer) Lister() v1.StatefulSetLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,7 +21,7 @@ package v1beta1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||
apps_v1beta1 "k8s.io/api/apps/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
@@ -70,7 +70,7 @@ func NewFilteredControllerRevisionInformer(client kubernetes.Interface, namespac
|
||||
return client.AppsV1beta1().ControllerRevisions(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&appsv1beta1.ControllerRevision{},
|
||||
&apps_v1beta1.ControllerRevision{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *controllerRevisionInformer) defaultInformer(client kubernetes.Interface
|
||||
}
|
||||
|
||||
func (f *controllerRevisionInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&appsv1beta1.ControllerRevision{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&apps_v1beta1.ControllerRevision{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *controllerRevisionInformer) Lister() v1beta1.ControllerRevisionLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,7 +21,7 @@ package v1beta1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||
apps_v1beta1 "k8s.io/api/apps/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
@@ -70,7 +70,7 @@ func NewFilteredDeploymentInformer(client kubernetes.Interface, namespace string
|
||||
return client.AppsV1beta1().Deployments(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&appsv1beta1.Deployment{},
|
||||
&apps_v1beta1.Deployment{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *deploymentInformer) defaultInformer(client kubernetes.Interface, resync
|
||||
}
|
||||
|
||||
func (f *deploymentInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&appsv1beta1.Deployment{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&apps_v1beta1.Deployment{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *deploymentInformer) Lister() v1beta1.DeploymentLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,7 +21,7 @@ package v1beta1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||
apps_v1beta1 "k8s.io/api/apps/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
@@ -70,7 +70,7 @@ func NewFilteredStatefulSetInformer(client kubernetes.Interface, namespace strin
|
||||
return client.AppsV1beta1().StatefulSets(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&appsv1beta1.StatefulSet{},
|
||||
&apps_v1beta1.StatefulSet{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *statefulSetInformer) defaultInformer(client kubernetes.Interface, resyn
|
||||
}
|
||||
|
||||
func (f *statefulSetInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&appsv1beta1.StatefulSet{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&apps_v1beta1.StatefulSet{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *statefulSetInformer) Lister() v1beta1.StatefulSetLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,7 +21,7 @@ package v1beta2
|
||||
import (
|
||||
time "time"
|
||||
|
||||
appsv1beta2 "k8s.io/api/apps/v1beta2"
|
||||
apps_v1beta2 "k8s.io/api/apps/v1beta2"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
@@ -70,7 +70,7 @@ func NewFilteredControllerRevisionInformer(client kubernetes.Interface, namespac
|
||||
return client.AppsV1beta2().ControllerRevisions(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&appsv1beta2.ControllerRevision{},
|
||||
&apps_v1beta2.ControllerRevision{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *controllerRevisionInformer) defaultInformer(client kubernetes.Interface
|
||||
}
|
||||
|
||||
func (f *controllerRevisionInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&appsv1beta2.ControllerRevision{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&apps_v1beta2.ControllerRevision{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *controllerRevisionInformer) Lister() v1beta2.ControllerRevisionLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,7 +21,7 @@ package v1beta2
|
||||
import (
|
||||
time "time"
|
||||
|
||||
appsv1beta2 "k8s.io/api/apps/v1beta2"
|
||||
apps_v1beta2 "k8s.io/api/apps/v1beta2"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
@@ -70,7 +70,7 @@ func NewFilteredDaemonSetInformer(client kubernetes.Interface, namespace string,
|
||||
return client.AppsV1beta2().DaemonSets(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&appsv1beta2.DaemonSet{},
|
||||
&apps_v1beta2.DaemonSet{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *daemonSetInformer) defaultInformer(client kubernetes.Interface, resyncP
|
||||
}
|
||||
|
||||
func (f *daemonSetInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&appsv1beta2.DaemonSet{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&apps_v1beta2.DaemonSet{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *daemonSetInformer) Lister() v1beta2.DaemonSetLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,7 +21,7 @@ package v1beta2
|
||||
import (
|
||||
time "time"
|
||||
|
||||
appsv1beta2 "k8s.io/api/apps/v1beta2"
|
||||
apps_v1beta2 "k8s.io/api/apps/v1beta2"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
@@ -70,7 +70,7 @@ func NewFilteredDeploymentInformer(client kubernetes.Interface, namespace string
|
||||
return client.AppsV1beta2().Deployments(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&appsv1beta2.Deployment{},
|
||||
&apps_v1beta2.Deployment{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *deploymentInformer) defaultInformer(client kubernetes.Interface, resync
|
||||
}
|
||||
|
||||
func (f *deploymentInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&appsv1beta2.Deployment{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&apps_v1beta2.Deployment{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *deploymentInformer) Lister() v1beta2.DeploymentLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,7 +21,7 @@ package v1beta2
|
||||
import (
|
||||
time "time"
|
||||
|
||||
appsv1beta2 "k8s.io/api/apps/v1beta2"
|
||||
apps_v1beta2 "k8s.io/api/apps/v1beta2"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
@@ -70,7 +70,7 @@ func NewFilteredReplicaSetInformer(client kubernetes.Interface, namespace string
|
||||
return client.AppsV1beta2().ReplicaSets(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&appsv1beta2.ReplicaSet{},
|
||||
&apps_v1beta2.ReplicaSet{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *replicaSetInformer) defaultInformer(client kubernetes.Interface, resync
|
||||
}
|
||||
|
||||
func (f *replicaSetInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&appsv1beta2.ReplicaSet{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&apps_v1beta2.ReplicaSet{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *replicaSetInformer) Lister() v1beta2.ReplicaSetLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,7 +21,7 @@ package v1beta2
|
||||
import (
|
||||
time "time"
|
||||
|
||||
appsv1beta2 "k8s.io/api/apps/v1beta2"
|
||||
apps_v1beta2 "k8s.io/api/apps/v1beta2"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
@@ -70,7 +70,7 @@ func NewFilteredStatefulSetInformer(client kubernetes.Interface, namespace strin
|
||||
return client.AppsV1beta2().StatefulSets(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&appsv1beta2.StatefulSet{},
|
||||
&apps_v1beta2.StatefulSet{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *statefulSetInformer) defaultInformer(client kubernetes.Interface, resyn
|
||||
}
|
||||
|
||||
func (f *statefulSetInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&appsv1beta2.StatefulSet{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&apps_v1beta2.StatefulSet{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *statefulSetInformer) Lister() v1beta2.StatefulSetLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,7 +21,6 @@ package autoscaling
|
||||
import (
|
||||
v1 "k8s.io/client-go/informers/autoscaling/v1"
|
||||
v2beta1 "k8s.io/client-go/informers/autoscaling/v2beta1"
|
||||
v2beta2 "k8s.io/client-go/informers/autoscaling/v2beta2"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
)
|
||||
|
||||
@@ -31,8 +30,6 @@ type Interface interface {
|
||||
V1() v1.Interface
|
||||
// V2beta1 provides access to shared informers for resources in V2beta1.
|
||||
V2beta1() v2beta1.Interface
|
||||
// V2beta2 provides access to shared informers for resources in V2beta2.
|
||||
V2beta2() v2beta2.Interface
|
||||
}
|
||||
|
||||
type group struct {
|
||||
@@ -55,8 +52,3 @@ func (g *group) V1() v1.Interface {
|
||||
func (g *group) V2beta1() v2beta1.Interface {
|
||||
return v2beta1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
|
||||
// V2beta2 returns a new v2beta2.Interface.
|
||||
func (g *group) V2beta2() v2beta2.Interface {
|
||||
return v2beta2.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
autoscalingv1 "k8s.io/api/autoscaling/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
autoscaling_v1 "k8s.io/api/autoscaling/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -57,20 +57,20 @@ func NewHorizontalPodAutoscalerInformer(client kubernetes.Interface, namespace s
|
||||
func NewFilteredHorizontalPodAutoscalerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.AutoscalingV1().HorizontalPodAutoscalers(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.AutoscalingV1().HorizontalPodAutoscalers(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&autoscalingv1.HorizontalPodAutoscaler{},
|
||||
&autoscaling_v1.HorizontalPodAutoscaler{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *horizontalPodAutoscalerInformer) defaultInformer(client kubernetes.Inte
|
||||
}
|
||||
|
||||
func (f *horizontalPodAutoscalerInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&autoscalingv1.HorizontalPodAutoscaler{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&autoscaling_v1.HorizontalPodAutoscaler{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *horizontalPodAutoscalerInformer) Lister() v1.HorizontalPodAutoscalerLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,7 +21,7 @@ package v2beta1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1"
|
||||
autoscaling_v2beta1 "k8s.io/api/autoscaling/v2beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
@@ -70,7 +70,7 @@ func NewFilteredHorizontalPodAutoscalerInformer(client kubernetes.Interface, nam
|
||||
return client.AutoscalingV2beta1().HorizontalPodAutoscalers(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&autoscalingv2beta1.HorizontalPodAutoscaler{},
|
||||
&autoscaling_v2beta1.HorizontalPodAutoscaler{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *horizontalPodAutoscalerInformer) defaultInformer(client kubernetes.Inte
|
||||
}
|
||||
|
||||
func (f *horizontalPodAutoscalerInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&autoscalingv2beta1.HorizontalPodAutoscaler{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&autoscaling_v2beta1.HorizontalPodAutoscaler{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *horizontalPodAutoscalerInformer) Lister() v2beta1.HorizontalPodAutoscalerLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
Copyright 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.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v2beta2
|
||||
|
||||
import (
|
||||
time "time"
|
||||
|
||||
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
kubernetes "k8s.io/client-go/kubernetes"
|
||||
v2beta2 "k8s.io/client-go/listers/autoscaling/v2beta2"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// HorizontalPodAutoscalerInformer provides access to a shared informer and lister for
|
||||
// HorizontalPodAutoscalers.
|
||||
type HorizontalPodAutoscalerInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v2beta2.HorizontalPodAutoscalerLister
|
||||
}
|
||||
|
||||
type horizontalPodAutoscalerInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewHorizontalPodAutoscalerInformer constructs a new informer for HorizontalPodAutoscaler type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewHorizontalPodAutoscalerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredHorizontalPodAutoscalerInformer(client, namespace, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredHorizontalPodAutoscalerInformer constructs a new informer for HorizontalPodAutoscaler type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredHorizontalPodAutoscalerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.AutoscalingV2beta2().HorizontalPodAutoscalers(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.AutoscalingV2beta2().HorizontalPodAutoscalers(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&autoscalingv2beta2.HorizontalPodAutoscaler{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *horizontalPodAutoscalerInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredHorizontalPodAutoscalerInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *horizontalPodAutoscalerInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&autoscalingv2beta2.HorizontalPodAutoscaler{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *horizontalPodAutoscalerInformer) Lister() v2beta2.HorizontalPodAutoscalerLister {
|
||||
return v2beta2.NewHorizontalPodAutoscalerLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
Copyright 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.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v2beta2
|
||||
|
||||
import (
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// HorizontalPodAutoscalers returns a HorizontalPodAutoscalerInformer.
|
||||
HorizontalPodAutoscalers() HorizontalPodAutoscalerInformer
|
||||
}
|
||||
|
||||
type version struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// HorizontalPodAutoscalers returns a HorizontalPodAutoscalerInformer.
|
||||
func (v *version) HorizontalPodAutoscalers() HorizontalPodAutoscalerInformer {
|
||||
return &horizontalPodAutoscalerInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
batch_v1 "k8s.io/api/batch/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -57,20 +57,20 @@ func NewJobInformer(client kubernetes.Interface, namespace string, resyncPeriod
|
||||
func NewFilteredJobInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.BatchV1().Jobs(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.BatchV1().Jobs(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&batchv1.Job{},
|
||||
&batch_v1.Job{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *jobInformer) defaultInformer(client kubernetes.Interface, resyncPeriod
|
||||
}
|
||||
|
||||
func (f *jobInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&batchv1.Job{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&batch_v1.Job{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *jobInformer) Lister() v1.JobLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,7 +21,7 @@ package v1beta1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
batchv1beta1 "k8s.io/api/batch/v1beta1"
|
||||
batch_v1beta1 "k8s.io/api/batch/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
@@ -70,7 +70,7 @@ func NewFilteredCronJobInformer(client kubernetes.Interface, namespace string, r
|
||||
return client.BatchV1beta1().CronJobs(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&batchv1beta1.CronJob{},
|
||||
&batch_v1beta1.CronJob{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *cronJobInformer) defaultInformer(client kubernetes.Interface, resyncPer
|
||||
}
|
||||
|
||||
func (f *cronJobInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&batchv1beta1.CronJob{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&batch_v1beta1.CronJob{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *cronJobInformer) Lister() v1beta1.CronJobLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,7 +21,7 @@ package v2alpha1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
batchv2alpha1 "k8s.io/api/batch/v2alpha1"
|
||||
batch_v2alpha1 "k8s.io/api/batch/v2alpha1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
@@ -70,7 +70,7 @@ func NewFilteredCronJobInformer(client kubernetes.Interface, namespace string, r
|
||||
return client.BatchV2alpha1().CronJobs(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&batchv2alpha1.CronJob{},
|
||||
&batch_v2alpha1.CronJob{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *cronJobInformer) defaultInformer(client kubernetes.Interface, resyncPer
|
||||
}
|
||||
|
||||
func (f *cronJobInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&batchv2alpha1.CronJob{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&batch_v2alpha1.CronJob{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *cronJobInformer) Lister() v2alpha1.CronJobLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,7 +21,7 @@ package v1beta1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
certificates_v1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
@@ -69,7 +69,7 @@ func NewFilteredCertificateSigningRequestInformer(client kubernetes.Interface, r
|
||||
return client.CertificatesV1beta1().CertificateSigningRequests().Watch(options)
|
||||
},
|
||||
},
|
||||
&certificatesv1beta1.CertificateSigningRequest{},
|
||||
&certificates_v1beta1.CertificateSigningRequest{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -80,7 +80,7 @@ func (f *certificateSigningRequestInformer) defaultInformer(client kubernetes.In
|
||||
}
|
||||
|
||||
func (f *certificateSigningRequestInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&certificatesv1beta1.CertificateSigningRequest{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&certificates_v1beta1.CertificateSigningRequest{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *certificateSigningRequestInformer) Lister() v1beta1.CertificateSigningRequestLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
Copyright 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.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package coordination
|
||||
|
||||
import (
|
||||
v1beta1 "k8s.io/client-go/informers/coordination/v1beta1"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to each of this group's versions.
|
||||
type Interface interface {
|
||||
// V1beta1 provides access to shared informers for resources in V1beta1.
|
||||
V1beta1() v1beta1.Interface
|
||||
}
|
||||
|
||||
type group struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// V1beta1 returns a new v1beta1.Interface.
|
||||
func (g *group) V1beta1() v1beta1.Interface {
|
||||
return v1beta1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
Copyright 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.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// Leases returns a LeaseInformer.
|
||||
Leases() LeaseInformer
|
||||
}
|
||||
|
||||
type version struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// Leases returns a LeaseInformer.
|
||||
func (v *version) Leases() LeaseInformer {
|
||||
return &leaseInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
Copyright 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.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
time "time"
|
||||
|
||||
coordinationv1beta1 "k8s.io/api/coordination/v1beta1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
kubernetes "k8s.io/client-go/kubernetes"
|
||||
v1beta1 "k8s.io/client-go/listers/coordination/v1beta1"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// LeaseInformer provides access to a shared informer and lister for
|
||||
// Leases.
|
||||
type LeaseInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1beta1.LeaseLister
|
||||
}
|
||||
|
||||
type leaseInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewLeaseInformer constructs a new informer for Lease type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewLeaseInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredLeaseInformer(client, namespace, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredLeaseInformer constructs a new informer for Lease type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredLeaseInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoordinationV1beta1().Leases(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoordinationV1beta1().Leases(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&coordinationv1beta1.Lease{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *leaseInformer) defaultInformer(client kubernetes.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredLeaseInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *leaseInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&coordinationv1beta1.Lease{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *leaseInformer) Lister() v1beta1.LeaseLister {
|
||||
return v1beta1.NewLeaseLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
core_v1 "k8s.io/api/core/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -56,20 +56,20 @@ func NewComponentStatusInformer(client kubernetes.Interface, resyncPeriod time.D
|
||||
func NewFilteredComponentStatusInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().ComponentStatuses().List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().ComponentStatuses().Watch(options)
|
||||
},
|
||||
},
|
||||
&corev1.ComponentStatus{},
|
||||
&core_v1.ComponentStatus{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -80,7 +80,7 @@ func (f *componentStatusInformer) defaultInformer(client kubernetes.Interface, r
|
||||
}
|
||||
|
||||
func (f *componentStatusInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&corev1.ComponentStatus{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&core_v1.ComponentStatus{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *componentStatusInformer) Lister() v1.ComponentStatusLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
core_v1 "k8s.io/api/core/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -57,20 +57,20 @@ func NewConfigMapInformer(client kubernetes.Interface, namespace string, resyncP
|
||||
func NewFilteredConfigMapInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().ConfigMaps(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().ConfigMaps(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&corev1.ConfigMap{},
|
||||
&core_v1.ConfigMap{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *configMapInformer) defaultInformer(client kubernetes.Interface, resyncP
|
||||
}
|
||||
|
||||
func (f *configMapInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&corev1.ConfigMap{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&core_v1.ConfigMap{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *configMapInformer) Lister() v1.ConfigMapLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
core_v1 "k8s.io/api/core/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -57,20 +57,20 @@ func NewEndpointsInformer(client kubernetes.Interface, namespace string, resyncP
|
||||
func NewFilteredEndpointsInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().Endpoints(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().Endpoints(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&corev1.Endpoints{},
|
||||
&core_v1.Endpoints{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *endpointsInformer) defaultInformer(client kubernetes.Interface, resyncP
|
||||
}
|
||||
|
||||
func (f *endpointsInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&corev1.Endpoints{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&core_v1.Endpoints{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *endpointsInformer) Lister() v1.EndpointsLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
core_v1 "k8s.io/api/core/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -57,20 +57,20 @@ func NewEventInformer(client kubernetes.Interface, namespace string, resyncPerio
|
||||
func NewFilteredEventInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().Events(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().Events(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&corev1.Event{},
|
||||
&core_v1.Event{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *eventInformer) defaultInformer(client kubernetes.Interface, resyncPerio
|
||||
}
|
||||
|
||||
func (f *eventInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&corev1.Event{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&core_v1.Event{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *eventInformer) Lister() v1.EventLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
core_v1 "k8s.io/api/core/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -57,20 +57,20 @@ func NewLimitRangeInformer(client kubernetes.Interface, namespace string, resync
|
||||
func NewFilteredLimitRangeInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().LimitRanges(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().LimitRanges(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&corev1.LimitRange{},
|
||||
&core_v1.LimitRange{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *limitRangeInformer) defaultInformer(client kubernetes.Interface, resync
|
||||
}
|
||||
|
||||
func (f *limitRangeInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&corev1.LimitRange{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&core_v1.LimitRange{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *limitRangeInformer) Lister() v1.LimitRangeLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
core_v1 "k8s.io/api/core/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -56,20 +56,20 @@ func NewNamespaceInformer(client kubernetes.Interface, resyncPeriod time.Duratio
|
||||
func NewFilteredNamespaceInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().Namespaces().List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().Namespaces().Watch(options)
|
||||
},
|
||||
},
|
||||
&corev1.Namespace{},
|
||||
&core_v1.Namespace{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -80,7 +80,7 @@ func (f *namespaceInformer) defaultInformer(client kubernetes.Interface, resyncP
|
||||
}
|
||||
|
||||
func (f *namespaceInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&corev1.Namespace{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&core_v1.Namespace{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *namespaceInformer) Lister() v1.NamespaceLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
core_v1 "k8s.io/api/core/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -56,20 +56,20 @@ func NewNodeInformer(client kubernetes.Interface, resyncPeriod time.Duration, in
|
||||
func NewFilteredNodeInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().Nodes().List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().Nodes().Watch(options)
|
||||
},
|
||||
},
|
||||
&corev1.Node{},
|
||||
&core_v1.Node{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -80,7 +80,7 @@ func (f *nodeInformer) defaultInformer(client kubernetes.Interface, resyncPeriod
|
||||
}
|
||||
|
||||
func (f *nodeInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&corev1.Node{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&core_v1.Node{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *nodeInformer) Lister() v1.NodeLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
core_v1 "k8s.io/api/core/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -56,20 +56,20 @@ func NewPersistentVolumeInformer(client kubernetes.Interface, resyncPeriod time.
|
||||
func NewFilteredPersistentVolumeInformer(client kubernetes.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().PersistentVolumes().List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().PersistentVolumes().Watch(options)
|
||||
},
|
||||
},
|
||||
&corev1.PersistentVolume{},
|
||||
&core_v1.PersistentVolume{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -80,7 +80,7 @@ func (f *persistentVolumeInformer) defaultInformer(client kubernetes.Interface,
|
||||
}
|
||||
|
||||
func (f *persistentVolumeInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&corev1.PersistentVolume{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&core_v1.PersistentVolume{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *persistentVolumeInformer) Lister() v1.PersistentVolumeLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
core_v1 "k8s.io/api/core/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -57,20 +57,20 @@ func NewPersistentVolumeClaimInformer(client kubernetes.Interface, namespace str
|
||||
func NewFilteredPersistentVolumeClaimInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().PersistentVolumeClaims(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().PersistentVolumeClaims(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&corev1.PersistentVolumeClaim{},
|
||||
&core_v1.PersistentVolumeClaim{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *persistentVolumeClaimInformer) defaultInformer(client kubernetes.Interf
|
||||
}
|
||||
|
||||
func (f *persistentVolumeClaimInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&corev1.PersistentVolumeClaim{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&core_v1.PersistentVolumeClaim{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *persistentVolumeClaimInformer) Lister() v1.PersistentVolumeClaimLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
core_v1 "k8s.io/api/core/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -57,20 +57,20 @@ func NewPodInformer(client kubernetes.Interface, namespace string, resyncPeriod
|
||||
func NewFilteredPodInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().Pods(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().Pods(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&corev1.Pod{},
|
||||
&core_v1.Pod{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *podInformer) defaultInformer(client kubernetes.Interface, resyncPeriod
|
||||
}
|
||||
|
||||
func (f *podInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&corev1.Pod{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&core_v1.Pod{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *podInformer) Lister() v1.PodLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
core_v1 "k8s.io/api/core/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -57,20 +57,20 @@ func NewPodTemplateInformer(client kubernetes.Interface, namespace string, resyn
|
||||
func NewFilteredPodTemplateInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().PodTemplates(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().PodTemplates(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&corev1.PodTemplate{},
|
||||
&core_v1.PodTemplate{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *podTemplateInformer) defaultInformer(client kubernetes.Interface, resyn
|
||||
}
|
||||
|
||||
func (f *podTemplateInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&corev1.PodTemplate{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&core_v1.PodTemplate{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *podTemplateInformer) Lister() v1.PodTemplateLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
core_v1 "k8s.io/api/core/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -57,20 +57,20 @@ func NewReplicationControllerInformer(client kubernetes.Interface, namespace str
|
||||
func NewFilteredReplicationControllerInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().ReplicationControllers(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().ReplicationControllers(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&corev1.ReplicationController{},
|
||||
&core_v1.ReplicationController{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *replicationControllerInformer) defaultInformer(client kubernetes.Interf
|
||||
}
|
||||
|
||||
func (f *replicationControllerInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&corev1.ReplicationController{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&core_v1.ReplicationController{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *replicationControllerInformer) Lister() v1.ReplicationControllerLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
core_v1 "k8s.io/api/core/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -57,20 +57,20 @@ func NewResourceQuotaInformer(client kubernetes.Interface, namespace string, res
|
||||
func NewFilteredResourceQuotaInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().ResourceQuotas(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().ResourceQuotas(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&corev1.ResourceQuota{},
|
||||
&core_v1.ResourceQuota{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *resourceQuotaInformer) defaultInformer(client kubernetes.Interface, res
|
||||
}
|
||||
|
||||
func (f *resourceQuotaInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&corev1.ResourceQuota{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&core_v1.ResourceQuota{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *resourceQuotaInformer) Lister() v1.ResourceQuotaLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
core_v1 "k8s.io/api/core/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -57,20 +57,20 @@ func NewSecretInformer(client kubernetes.Interface, namespace string, resyncPeri
|
||||
func NewFilteredSecretInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().Secrets(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().Secrets(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&corev1.Secret{},
|
||||
&core_v1.Secret{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *secretInformer) defaultInformer(client kubernetes.Interface, resyncPeri
|
||||
}
|
||||
|
||||
func (f *secretInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&corev1.Secret{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&core_v1.Secret{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *secretInformer) Lister() v1.SecretLister {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
Copyright 2019 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.
|
||||
@@ -21,8 +21,8 @@ package v1
|
||||
import (
|
||||
time "time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
core_v1 "k8s.io/api/core/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
internalinterfaces "k8s.io/client-go/informers/internalinterfaces"
|
||||
@@ -57,20 +57,20 @@ func NewServiceInformer(client kubernetes.Interface, namespace string, resyncPer
|
||||
func NewFilteredServiceInformer(client kubernetes.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().Services(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.CoreV1().Services(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&corev1.Service{},
|
||||
&core_v1.Service{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,7 +81,7 @@ func (f *serviceInformer) defaultInformer(client kubernetes.Interface, resyncPer
|
||||
}
|
||||
|
||||
func (f *serviceInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&corev1.Service{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&core_v1.Service{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *serviceInformer) Lister() v1.ServiceLister {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user