Bump sigs.k8s.io/controller-runtime to v0.14.4 (#5507)
* Bump sigs.k8s.io/controller-runtime to v0.14.4 * Update gofmt
This commit is contained in:
2
vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/apimachinery.go
generated
vendored
2
vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/apimachinery.go
generated
vendored
@@ -81,7 +81,7 @@ func GVKForObject(obj runtime.Object, scheme *runtime.Scheme) (schema.GroupVersi
|
||||
// (unstructured, partial, etc)
|
||||
|
||||
// check for PartialObjectMetadata, which is analogous to unstructured, but isn't handled by ObjectKinds
|
||||
_, isPartial := obj.(*metav1.PartialObjectMetadata) //nolint:ifshort
|
||||
_, isPartial := obj.(*metav1.PartialObjectMetadata)
|
||||
_, isPartialList := obj.(*metav1.PartialObjectMetadataList)
|
||||
if isPartial || isPartialList {
|
||||
// we require that the GVK be populated in order to recognize the object
|
||||
|
||||
37
vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/dynamicrestmapper.go
generated
vendored
37
vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/dynamicrestmapper.go
generated
vendored
@@ -17,7 +17,6 @@ limitations under the License.
|
||||
package apiutil
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
@@ -41,6 +40,8 @@ type dynamicRESTMapper struct {
|
||||
// Used for lazy init.
|
||||
inited uint32
|
||||
initMtx sync.Mutex
|
||||
|
||||
useLazyRestmapper bool
|
||||
}
|
||||
|
||||
// DynamicRESTMapperOption is a functional option on the dynamicRESTMapper.
|
||||
@@ -61,6 +62,12 @@ var WithLazyDiscovery DynamicRESTMapperOption = func(drm *dynamicRESTMapper) err
|
||||
return nil
|
||||
}
|
||||
|
||||
// WithExperimentalLazyMapper enables experimental more advanced Lazy Restmapping mechanism.
|
||||
var WithExperimentalLazyMapper DynamicRESTMapperOption = func(drm *dynamicRESTMapper) error {
|
||||
drm.useLazyRestmapper = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// WithCustomMapper supports setting a custom RESTMapper refresher instead of
|
||||
// the default method, which uses a discovery client.
|
||||
//
|
||||
@@ -96,6 +103,9 @@ func NewDynamicRESTMapper(cfg *rest.Config, opts ...DynamicRESTMapperOption) (me
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if drm.useLazyRestmapper {
|
||||
return newLazyRESTMapperWithClient(client)
|
||||
}
|
||||
if !drm.lazy {
|
||||
if err := drm.setStaticMapper(); err != nil {
|
||||
return nil, err
|
||||
@@ -145,7 +155,7 @@ func (drm *dynamicRESTMapper) init() (err error) {
|
||||
// checkAndReload attempts to call the given callback, which is assumed to be dependent
|
||||
// on the data in the restmapper.
|
||||
//
|
||||
// If the callback returns an error that matches the given error, it will attempt to reload
|
||||
// If the callback returns an error matching meta.IsNoMatchErr, it will attempt to reload
|
||||
// the RESTMapper's data and re-call the callback once that's occurred.
|
||||
// If the callback returns any other error, the function will return immediately regardless.
|
||||
//
|
||||
@@ -154,7 +164,7 @@ func (drm *dynamicRESTMapper) init() (err error) {
|
||||
// the callback.
|
||||
// It's thread-safe, and worries about thread-safety for the callback (so the callback does
|
||||
// not need to attempt to lock the restmapper).
|
||||
func (drm *dynamicRESTMapper) checkAndReload(needsReloadErr error, checkNeedsReload func() error) error {
|
||||
func (drm *dynamicRESTMapper) checkAndReload(checkNeedsReload func() error) error {
|
||||
// first, check the common path -- data is fresh enough
|
||||
// (use an IIFE for the lock's defer)
|
||||
err := func() error {
|
||||
@@ -164,10 +174,7 @@ func (drm *dynamicRESTMapper) checkAndReload(needsReloadErr error, checkNeedsRel
|
||||
return checkNeedsReload()
|
||||
}()
|
||||
|
||||
// NB(directxman12): `Is` and `As` have a confusing relationship --
|
||||
// `Is` is like `== or does this implement .Is`, whereas `As` says
|
||||
// `can I type-assert into`
|
||||
needsReload := errors.As(err, &needsReloadErr)
|
||||
needsReload := meta.IsNoMatchError(err)
|
||||
if !needsReload {
|
||||
return err
|
||||
}
|
||||
@@ -178,7 +185,7 @@ func (drm *dynamicRESTMapper) checkAndReload(needsReloadErr error, checkNeedsRel
|
||||
|
||||
// ... and double-check that we didn't reload in the meantime
|
||||
err = checkNeedsReload()
|
||||
needsReload = errors.As(err, &needsReloadErr)
|
||||
needsReload = meta.IsNoMatchError(err)
|
||||
if !needsReload {
|
||||
return err
|
||||
}
|
||||
@@ -206,7 +213,7 @@ func (drm *dynamicRESTMapper) KindFor(resource schema.GroupVersionResource) (sch
|
||||
return schema.GroupVersionKind{}, err
|
||||
}
|
||||
var gvk schema.GroupVersionKind
|
||||
err := drm.checkAndReload(&meta.NoResourceMatchError{}, func() error {
|
||||
err := drm.checkAndReload(func() error {
|
||||
var err error
|
||||
gvk, err = drm.staticMapper.KindFor(resource)
|
||||
return err
|
||||
@@ -219,7 +226,7 @@ func (drm *dynamicRESTMapper) KindsFor(resource schema.GroupVersionResource) ([]
|
||||
return nil, err
|
||||
}
|
||||
var gvks []schema.GroupVersionKind
|
||||
err := drm.checkAndReload(&meta.NoResourceMatchError{}, func() error {
|
||||
err := drm.checkAndReload(func() error {
|
||||
var err error
|
||||
gvks, err = drm.staticMapper.KindsFor(resource)
|
||||
return err
|
||||
@@ -233,7 +240,7 @@ func (drm *dynamicRESTMapper) ResourceFor(input schema.GroupVersionResource) (sc
|
||||
}
|
||||
|
||||
var gvr schema.GroupVersionResource
|
||||
err := drm.checkAndReload(&meta.NoResourceMatchError{}, func() error {
|
||||
err := drm.checkAndReload(func() error {
|
||||
var err error
|
||||
gvr, err = drm.staticMapper.ResourceFor(input)
|
||||
return err
|
||||
@@ -246,7 +253,7 @@ func (drm *dynamicRESTMapper) ResourcesFor(input schema.GroupVersionResource) ([
|
||||
return nil, err
|
||||
}
|
||||
var gvrs []schema.GroupVersionResource
|
||||
err := drm.checkAndReload(&meta.NoResourceMatchError{}, func() error {
|
||||
err := drm.checkAndReload(func() error {
|
||||
var err error
|
||||
gvrs, err = drm.staticMapper.ResourcesFor(input)
|
||||
return err
|
||||
@@ -259,7 +266,7 @@ func (drm *dynamicRESTMapper) RESTMapping(gk schema.GroupKind, versions ...strin
|
||||
return nil, err
|
||||
}
|
||||
var mapping *meta.RESTMapping
|
||||
err := drm.checkAndReload(&meta.NoKindMatchError{}, func() error {
|
||||
err := drm.checkAndReload(func() error {
|
||||
var err error
|
||||
mapping, err = drm.staticMapper.RESTMapping(gk, versions...)
|
||||
return err
|
||||
@@ -272,7 +279,7 @@ func (drm *dynamicRESTMapper) RESTMappings(gk schema.GroupKind, versions ...stri
|
||||
return nil, err
|
||||
}
|
||||
var mappings []*meta.RESTMapping
|
||||
err := drm.checkAndReload(&meta.NoKindMatchError{}, func() error {
|
||||
err := drm.checkAndReload(func() error {
|
||||
var err error
|
||||
mappings, err = drm.staticMapper.RESTMappings(gk, versions...)
|
||||
return err
|
||||
@@ -285,7 +292,7 @@ func (drm *dynamicRESTMapper) ResourceSingularizer(resource string) (string, err
|
||||
return "", err
|
||||
}
|
||||
var singular string
|
||||
err := drm.checkAndReload(&meta.NoResourceMatchError{}, func() error {
|
||||
err := drm.checkAndReload(func() error {
|
||||
var err error
|
||||
singular, err = drm.staticMapper.ResourceSingularizer(resource)
|
||||
return err
|
||||
|
||||
248
vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/lazyrestmapper.go
generated
vendored
Normal file
248
vendor/sigs.k8s.io/controller-runtime/pkg/client/apiutil/lazyrestmapper.go
generated
vendored
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
Copyright 2023 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 apiutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"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"
|
||||
"k8s.io/client-go/restmapper"
|
||||
)
|
||||
|
||||
// lazyRESTMapper is a RESTMapper that will lazily query the provided
|
||||
// client for discovery information to do REST mappings.
|
||||
type lazyRESTMapper struct {
|
||||
mapper meta.RESTMapper
|
||||
client *discovery.DiscoveryClient
|
||||
knownGroups map[string]*restmapper.APIGroupResources
|
||||
apiGroups *metav1.APIGroupList
|
||||
|
||||
// mutex to provide thread-safe mapper reloading.
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
// newLazyRESTMapperWithClient initializes a LazyRESTMapper with a custom discovery client.
|
||||
func newLazyRESTMapperWithClient(discoveryClient *discovery.DiscoveryClient) (meta.RESTMapper, error) {
|
||||
return &lazyRESTMapper{
|
||||
mapper: restmapper.NewDiscoveryRESTMapper([]*restmapper.APIGroupResources{}),
|
||||
client: discoveryClient,
|
||||
knownGroups: map[string]*restmapper.APIGroupResources{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// KindFor implements Mapper.KindFor.
|
||||
func (m *lazyRESTMapper) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) {
|
||||
res, err := m.mapper.KindFor(resource)
|
||||
if meta.IsNoMatchError(err) {
|
||||
if err = m.addKnownGroupAndReload(resource.Group, resource.Version); err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
res, err = m.mapper.KindFor(resource)
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
// KindsFor implements Mapper.KindsFor.
|
||||
func (m *lazyRESTMapper) KindsFor(resource schema.GroupVersionResource) ([]schema.GroupVersionKind, error) {
|
||||
res, err := m.mapper.KindsFor(resource)
|
||||
if meta.IsNoMatchError(err) {
|
||||
if err = m.addKnownGroupAndReload(resource.Group, resource.Version); err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
res, err = m.mapper.KindsFor(resource)
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
// ResourceFor implements Mapper.ResourceFor.
|
||||
func (m *lazyRESTMapper) ResourceFor(input schema.GroupVersionResource) (schema.GroupVersionResource, error) {
|
||||
res, err := m.mapper.ResourceFor(input)
|
||||
if meta.IsNoMatchError(err) {
|
||||
if err = m.addKnownGroupAndReload(input.Group, input.Version); err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
res, err = m.mapper.ResourceFor(input)
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
// ResourcesFor implements Mapper.ResourcesFor.
|
||||
func (m *lazyRESTMapper) ResourcesFor(input schema.GroupVersionResource) ([]schema.GroupVersionResource, error) {
|
||||
res, err := m.mapper.ResourcesFor(input)
|
||||
if meta.IsNoMatchError(err) {
|
||||
if err = m.addKnownGroupAndReload(input.Group, input.Version); err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
res, err = m.mapper.ResourcesFor(input)
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
// RESTMapping implements Mapper.RESTMapping.
|
||||
func (m *lazyRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string) (*meta.RESTMapping, error) {
|
||||
res, err := m.mapper.RESTMapping(gk, versions...)
|
||||
if meta.IsNoMatchError(err) {
|
||||
if err = m.addKnownGroupAndReload(gk.Group, versions...); err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
res, err = m.mapper.RESTMapping(gk, versions...)
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
// RESTMappings implements Mapper.RESTMappings.
|
||||
func (m *lazyRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string) ([]*meta.RESTMapping, error) {
|
||||
res, err := m.mapper.RESTMappings(gk, versions...)
|
||||
if meta.IsNoMatchError(err) {
|
||||
if err = m.addKnownGroupAndReload(gk.Group, versions...); err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
res, err = m.mapper.RESTMappings(gk, versions...)
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
// ResourceSingularizer implements Mapper.ResourceSingularizer.
|
||||
func (m *lazyRESTMapper) ResourceSingularizer(resource string) (string, error) {
|
||||
return m.mapper.ResourceSingularizer(resource)
|
||||
}
|
||||
|
||||
// addKnownGroupAndReload reloads the mapper with updated information about missing API group.
|
||||
// versions can be specified for partial updates, for instance for v1beta1 version only.
|
||||
func (m *lazyRESTMapper) addKnownGroupAndReload(groupName string, versions ...string) error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
// If no specific versions are set by user, we will scan all available ones for the API group.
|
||||
// This operation requires 2 requests: /api and /apis, but only once. For all subsequent calls
|
||||
// this data will be taken from cache.
|
||||
if len(versions) == 0 {
|
||||
apiGroup, err := m.findAPIGroupByName(groupName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, version := range apiGroup.Versions {
|
||||
versions = append(versions, version.Version)
|
||||
}
|
||||
}
|
||||
|
||||
// Create or fetch group resources from cache.
|
||||
groupResources := &restmapper.APIGroupResources{
|
||||
Group: metav1.APIGroup{Name: groupName},
|
||||
VersionedResources: make(map[string][]metav1.APIResource),
|
||||
}
|
||||
if _, ok := m.knownGroups[groupName]; ok {
|
||||
groupResources = m.knownGroups[groupName]
|
||||
}
|
||||
|
||||
// Update information for group resources about versioned resources.
|
||||
// The number of API calls is equal to the number of versions: /apis/<group>/<version>.
|
||||
groupVersionResources, err := m.fetchGroupVersionResources(groupName, versions...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get API group resources: %w", err)
|
||||
}
|
||||
for version, resources := range groupVersionResources {
|
||||
groupResources.VersionedResources[version.Version] = resources.APIResources
|
||||
}
|
||||
|
||||
// Update information for group resources about the API group by adding new versions.
|
||||
for _, version := range versions {
|
||||
groupResources.Group.Versions = append(groupResources.Group.Versions, metav1.GroupVersionForDiscovery{
|
||||
GroupVersion: metav1.GroupVersion{Group: groupName, Version: version}.String(),
|
||||
Version: version,
|
||||
})
|
||||
}
|
||||
|
||||
// Update data in the cache.
|
||||
m.knownGroups[groupName] = groupResources
|
||||
|
||||
// Finally, update the group with received information and regenerate the mapper.
|
||||
updatedGroupResources := make([]*restmapper.APIGroupResources, 0, len(m.knownGroups))
|
||||
for _, agr := range m.knownGroups {
|
||||
updatedGroupResources = append(updatedGroupResources, agr)
|
||||
}
|
||||
|
||||
m.mapper = restmapper.NewDiscoveryRESTMapper(updatedGroupResources)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// findAPIGroupByName returns API group by its name.
|
||||
func (m *lazyRESTMapper) findAPIGroupByName(groupName string) (metav1.APIGroup, error) {
|
||||
// Ensure that required info about existing API groups is received and stored in the mapper.
|
||||
// It will make 2 API calls to /api and /apis, but only once.
|
||||
if m.apiGroups == nil {
|
||||
apiGroups, err := m.client.ServerGroups()
|
||||
if err != nil {
|
||||
return metav1.APIGroup{}, fmt.Errorf("failed to get server groups: %w", err)
|
||||
}
|
||||
if len(apiGroups.Groups) == 0 {
|
||||
return metav1.APIGroup{}, fmt.Errorf("received an empty API groups list")
|
||||
}
|
||||
|
||||
m.apiGroups = apiGroups
|
||||
}
|
||||
|
||||
for i := range m.apiGroups.Groups {
|
||||
if groupName == (&m.apiGroups.Groups[i]).Name {
|
||||
return m.apiGroups.Groups[i], nil
|
||||
}
|
||||
}
|
||||
|
||||
return metav1.APIGroup{}, fmt.Errorf("failed to find API group %s", groupName)
|
||||
}
|
||||
|
||||
// fetchGroupVersionResources fetches the resources for the specified group and its versions.
|
||||
func (m *lazyRESTMapper) fetchGroupVersionResources(groupName string, versions ...string) (map[schema.GroupVersion]*metav1.APIResourceList, error) {
|
||||
groupVersionResources := make(map[schema.GroupVersion]*metav1.APIResourceList)
|
||||
failedGroups := make(map[schema.GroupVersion]error)
|
||||
|
||||
for _, version := range versions {
|
||||
groupVersion := schema.GroupVersion{Group: groupName, Version: version}
|
||||
|
||||
apiResourceList, err := m.client.ServerResourcesForGroupVersion(groupVersion.String())
|
||||
if err != nil {
|
||||
failedGroups[groupVersion] = err
|
||||
}
|
||||
if apiResourceList != nil {
|
||||
// even in case of error, some fallback might have been returned.
|
||||
groupVersionResources[groupVersion] = apiResourceList
|
||||
}
|
||||
}
|
||||
|
||||
if len(failedGroups) > 0 {
|
||||
return nil, &discovery.ErrGroupDiscoveryFailed{Groups: failedGroups}
|
||||
}
|
||||
|
||||
return groupVersionResources, nil
|
||||
}
|
||||
214
vendor/sigs.k8s.io/controller-runtime/pkg/client/client.go
generated
vendored
214
vendor/sigs.k8s.io/controller-runtime/pkg/client/client.go
generated
vendored
@@ -18,6 +18,7 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
@@ -45,7 +46,7 @@ type WarningHandlerOptions struct {
|
||||
// AllowDuplicateLogs does not deduplicate the to-be
|
||||
// logged surfaced warnings messages. See
|
||||
// log.WarningHandlerOptions for considerations
|
||||
// regarding deuplication
|
||||
// regarding deduplication
|
||||
AllowDuplicateLogs bool
|
||||
}
|
||||
|
||||
@@ -88,13 +89,12 @@ func newClient(config *rest.Config, options Options) (*client, error) {
|
||||
// is log.KubeAPIWarningLogger with deduplication enabled.
|
||||
// See log.KubeAPIWarningLoggerOptions for considerations
|
||||
// regarding deduplication.
|
||||
rest.SetDefaultWarningHandler(
|
||||
log.NewKubeAPIWarningLogger(
|
||||
logger,
|
||||
log.KubeAPIWarningLoggerOptions{
|
||||
Deduplicate: !options.Opts.AllowDuplicateLogs,
|
||||
},
|
||||
),
|
||||
config = rest.CopyConfig(config)
|
||||
config.WarningHandler = log.NewKubeAPIWarningLogger(
|
||||
logger,
|
||||
log.KubeAPIWarningLoggerOptions{
|
||||
Deduplicate: !options.Opts.AllowDuplicateLogs,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -241,16 +241,16 @@ func (c *client) Patch(ctx context.Context, obj Object, patch Patch, opts ...Pat
|
||||
}
|
||||
|
||||
// Get implements client.Client.
|
||||
func (c *client) Get(ctx context.Context, key ObjectKey, obj Object) error {
|
||||
func (c *client) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error {
|
||||
switch obj.(type) {
|
||||
case *unstructured.Unstructured:
|
||||
return c.unstructuredClient.Get(ctx, key, obj)
|
||||
return c.unstructuredClient.Get(ctx, key, obj, opts...)
|
||||
case *metav1.PartialObjectMetadata:
|
||||
// Metadata only object should always preserve the GVK coming in from the caller.
|
||||
defer c.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind())
|
||||
return c.metadataClient.Get(ctx, key, obj)
|
||||
return c.metadataClient.Get(ctx, key, obj, opts...)
|
||||
default:
|
||||
return c.typedClient.Get(ctx, key, obj)
|
||||
return c.typedClient.Get(ctx, key, obj, opts...)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,40 +289,194 @@ func (c *client) List(ctx context.Context, obj ObjectList, opts ...ListOption) e
|
||||
}
|
||||
|
||||
// Status implements client.StatusClient.
|
||||
func (c *client) Status() StatusWriter {
|
||||
return &statusWriter{client: c}
|
||||
func (c *client) Status() SubResourceWriter {
|
||||
return c.SubResource("status")
|
||||
}
|
||||
|
||||
// statusWriter is client.StatusWriter that writes status subresource.
|
||||
type statusWriter struct {
|
||||
client *client
|
||||
func (c *client) SubResource(subResource string) SubResourceClient {
|
||||
return &subResourceClient{client: c, subResource: subResource}
|
||||
}
|
||||
|
||||
// ensure statusWriter implements client.StatusWriter.
|
||||
var _ StatusWriter = &statusWriter{}
|
||||
// subResourceClient is client.SubResourceWriter that writes to subresources.
|
||||
type subResourceClient struct {
|
||||
client *client
|
||||
subResource string
|
||||
}
|
||||
|
||||
// Update implements client.StatusWriter.
|
||||
func (sw *statusWriter) Update(ctx context.Context, obj Object, opts ...UpdateOption) error {
|
||||
defer sw.client.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind())
|
||||
// ensure subResourceClient implements client.SubResourceClient.
|
||||
var _ SubResourceClient = &subResourceClient{}
|
||||
|
||||
// SubResourceGetOptions holds all the possible configuration
|
||||
// for a subresource Get request.
|
||||
type SubResourceGetOptions struct {
|
||||
Raw *metav1.GetOptions
|
||||
}
|
||||
|
||||
// ApplyToSubResourceGet updates the configuaration to the given get options.
|
||||
func (getOpt *SubResourceGetOptions) ApplyToSubResourceGet(o *SubResourceGetOptions) {
|
||||
if getOpt.Raw != nil {
|
||||
o.Raw = getOpt.Raw
|
||||
}
|
||||
}
|
||||
|
||||
// ApplyOptions applues the given options.
|
||||
func (getOpt *SubResourceGetOptions) ApplyOptions(opts []SubResourceGetOption) *SubResourceGetOptions {
|
||||
for _, o := range opts {
|
||||
o.ApplyToSubResourceGet(getOpt)
|
||||
}
|
||||
|
||||
return getOpt
|
||||
}
|
||||
|
||||
// AsGetOptions returns the configured options as *metav1.GetOptions.
|
||||
func (getOpt *SubResourceGetOptions) AsGetOptions() *metav1.GetOptions {
|
||||
if getOpt.Raw == nil {
|
||||
return &metav1.GetOptions{}
|
||||
}
|
||||
return getOpt.Raw
|
||||
}
|
||||
|
||||
// SubResourceUpdateOptions holds all the possible configuration
|
||||
// for a subresource update request.
|
||||
type SubResourceUpdateOptions struct {
|
||||
UpdateOptions
|
||||
SubResourceBody Object
|
||||
}
|
||||
|
||||
// ApplyToSubResourceUpdate updates the configuration on the given create options
|
||||
func (uo *SubResourceUpdateOptions) ApplyToSubResourceUpdate(o *SubResourceUpdateOptions) {
|
||||
uo.UpdateOptions.ApplyToUpdate(&o.UpdateOptions)
|
||||
if uo.SubResourceBody != nil {
|
||||
o.SubResourceBody = uo.SubResourceBody
|
||||
}
|
||||
}
|
||||
|
||||
// ApplyOptions applies the given options.
|
||||
func (uo *SubResourceUpdateOptions) ApplyOptions(opts []SubResourceUpdateOption) *SubResourceUpdateOptions {
|
||||
for _, o := range opts {
|
||||
o.ApplyToSubResourceUpdate(uo)
|
||||
}
|
||||
|
||||
return uo
|
||||
}
|
||||
|
||||
// SubResourceUpdateAndPatchOption is an option that can be used for either
|
||||
// a subresource update or patch request.
|
||||
type SubResourceUpdateAndPatchOption interface {
|
||||
SubResourceUpdateOption
|
||||
SubResourcePatchOption
|
||||
}
|
||||
|
||||
// WithSubResourceBody returns an option that uses the given body
|
||||
// for a subresource Update or Patch operation.
|
||||
func WithSubResourceBody(body Object) SubResourceUpdateAndPatchOption {
|
||||
return &withSubresourceBody{body: body}
|
||||
}
|
||||
|
||||
type withSubresourceBody struct {
|
||||
body Object
|
||||
}
|
||||
|
||||
func (wsr *withSubresourceBody) ApplyToSubResourceUpdate(o *SubResourceUpdateOptions) {
|
||||
o.SubResourceBody = wsr.body
|
||||
}
|
||||
|
||||
func (wsr *withSubresourceBody) ApplyToSubResourcePatch(o *SubResourcePatchOptions) {
|
||||
o.SubResourceBody = wsr.body
|
||||
}
|
||||
|
||||
// SubResourceCreateOptions are all the possible configurations for a subresource
|
||||
// create request.
|
||||
type SubResourceCreateOptions struct {
|
||||
CreateOptions
|
||||
}
|
||||
|
||||
// ApplyOptions applies the given options.
|
||||
func (co *SubResourceCreateOptions) ApplyOptions(opts []SubResourceCreateOption) *SubResourceCreateOptions {
|
||||
for _, o := range opts {
|
||||
o.ApplyToSubResourceCreate(co)
|
||||
}
|
||||
|
||||
return co
|
||||
}
|
||||
|
||||
// ApplyToSubresourceCreate applies the the configuration on the given create options.
|
||||
func (co *SubResourceCreateOptions) ApplyToSubresourceCreate(o *SubResourceCreateOptions) {
|
||||
co.CreateOptions.ApplyToCreate(&co.CreateOptions)
|
||||
}
|
||||
|
||||
// SubResourcePatchOptions holds all possible configurations for a subresource patch
|
||||
// request.
|
||||
type SubResourcePatchOptions struct {
|
||||
PatchOptions
|
||||
SubResourceBody Object
|
||||
}
|
||||
|
||||
// ApplyOptions applies the given options.
|
||||
func (po *SubResourcePatchOptions) ApplyOptions(opts []SubResourcePatchOption) *SubResourcePatchOptions {
|
||||
for _, o := range opts {
|
||||
o.ApplyToSubResourcePatch(po)
|
||||
}
|
||||
|
||||
return po
|
||||
}
|
||||
|
||||
// ApplyToSubResourcePatch applies the configuration on the given patch options.
|
||||
func (po *SubResourcePatchOptions) ApplyToSubResourcePatch(o *SubResourcePatchOptions) {
|
||||
po.PatchOptions.ApplyToPatch(&o.PatchOptions)
|
||||
if po.SubResourceBody != nil {
|
||||
o.SubResourceBody = po.SubResourceBody
|
||||
}
|
||||
}
|
||||
|
||||
func (sc *subResourceClient) Get(ctx context.Context, obj Object, subResource Object, opts ...SubResourceGetOption) error {
|
||||
switch obj.(type) {
|
||||
case *unstructured.Unstructured:
|
||||
return sw.client.unstructuredClient.UpdateStatus(ctx, obj, opts...)
|
||||
return sc.client.unstructuredClient.GetSubResource(ctx, obj, subResource, sc.subResource, opts...)
|
||||
case *metav1.PartialObjectMetadata:
|
||||
return errors.New("can not get subresource using only metadata")
|
||||
default:
|
||||
return sc.client.typedClient.GetSubResource(ctx, obj, subResource, sc.subResource, opts...)
|
||||
}
|
||||
}
|
||||
|
||||
// Create implements client.SubResourceClient
|
||||
func (sc *subResourceClient) Create(ctx context.Context, obj Object, subResource Object, opts ...SubResourceCreateOption) error {
|
||||
defer sc.client.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind())
|
||||
defer sc.client.resetGroupVersionKind(subResource, subResource.GetObjectKind().GroupVersionKind())
|
||||
|
||||
switch obj.(type) {
|
||||
case *unstructured.Unstructured:
|
||||
return sc.client.unstructuredClient.CreateSubResource(ctx, obj, subResource, sc.subResource, opts...)
|
||||
case *metav1.PartialObjectMetadata:
|
||||
return fmt.Errorf("cannot update status using only metadata -- did you mean to patch?")
|
||||
default:
|
||||
return sw.client.typedClient.UpdateStatus(ctx, obj, opts...)
|
||||
return sc.client.typedClient.CreateSubResource(ctx, obj, subResource, sc.subResource, opts...)
|
||||
}
|
||||
}
|
||||
|
||||
// Patch implements client.Client.
|
||||
func (sw *statusWriter) Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error {
|
||||
defer sw.client.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind())
|
||||
// Update implements client.SubResourceClient
|
||||
func (sc *subResourceClient) Update(ctx context.Context, obj Object, opts ...SubResourceUpdateOption) error {
|
||||
defer sc.client.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind())
|
||||
switch obj.(type) {
|
||||
case *unstructured.Unstructured:
|
||||
return sw.client.unstructuredClient.PatchStatus(ctx, obj, patch, opts...)
|
||||
return sc.client.unstructuredClient.UpdateSubResource(ctx, obj, sc.subResource, opts...)
|
||||
case *metav1.PartialObjectMetadata:
|
||||
return sw.client.metadataClient.PatchStatus(ctx, obj, patch, opts...)
|
||||
return fmt.Errorf("cannot update status using only metadata -- did you mean to patch?")
|
||||
default:
|
||||
return sw.client.typedClient.PatchStatus(ctx, obj, patch, opts...)
|
||||
return sc.client.typedClient.UpdateSubResource(ctx, obj, sc.subResource, opts...)
|
||||
}
|
||||
}
|
||||
|
||||
// Patch implements client.SubResourceWriter.
|
||||
func (sc *subResourceClient) Patch(ctx context.Context, obj Object, patch Patch, opts ...SubResourcePatchOption) error {
|
||||
defer sc.client.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind())
|
||||
switch obj.(type) {
|
||||
case *unstructured.Unstructured:
|
||||
return sc.client.unstructuredClient.PatchSubResource(ctx, obj, sc.subResource, patch, opts...)
|
||||
case *metav1.PartialObjectMetadata:
|
||||
return sc.client.metadataClient.PatchSubResource(ctx, obj, sc.subResource, patch, opts...)
|
||||
default:
|
||||
return sc.client.typedClient.PatchSubResource(ctx, obj, sc.subResource, patch, opts...)
|
||||
}
|
||||
}
|
||||
|
||||
38
vendor/sigs.k8s.io/controller-runtime/pkg/client/config/config.go
generated
vendored
38
vendor/sigs.k8s.io/controller-runtime/pkg/client/config/config.go
generated
vendored
@@ -29,15 +29,32 @@ import (
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/internal/log"
|
||||
)
|
||||
|
||||
// KubeconfigFlagName is the name of the kubeconfig flag
|
||||
const KubeconfigFlagName = "kubeconfig"
|
||||
|
||||
var (
|
||||
kubeconfig string
|
||||
log = logf.RuntimeLog.WithName("client").WithName("config")
|
||||
)
|
||||
|
||||
// init registers the "kubeconfig" flag to the default command line FlagSet.
|
||||
// TODO: This should be removed, as it potentially leads to redefined flag errors for users, if they already
|
||||
// have registered the "kubeconfig" flag to the command line FlagSet in other parts of their code.
|
||||
func init() {
|
||||
// TODO: Fix this to allow double vendoring this library but still register flags on behalf of users
|
||||
flag.StringVar(&kubeconfig, "kubeconfig", "",
|
||||
"Paths to a kubeconfig. Only required if out-of-cluster.")
|
||||
RegisterFlags(flag.CommandLine)
|
||||
}
|
||||
|
||||
// RegisterFlags registers flag variables to the given FlagSet if not already registered.
|
||||
// It uses the default command line FlagSet, if none is provided. Currently, it only registers the kubeconfig flag.
|
||||
func RegisterFlags(fs *flag.FlagSet) {
|
||||
if fs == nil {
|
||||
fs = flag.CommandLine
|
||||
}
|
||||
if f := fs.Lookup(KubeconfigFlagName); f != nil {
|
||||
kubeconfig = f.Value.String()
|
||||
} else {
|
||||
fs.StringVar(&kubeconfig, KubeconfigFlagName, "", "Paths to a kubeconfig. Only required if out-of-cluster.")
|
||||
}
|
||||
}
|
||||
|
||||
// GetConfig creates a *rest.Config for talking to a Kubernetes API server.
|
||||
@@ -47,7 +64,7 @@ func init() {
|
||||
// It also applies saner defaults for QPS and burst based on the Kubernetes
|
||||
// controller manager defaults (20 QPS, 30 burst)
|
||||
//
|
||||
// Config precedence
|
||||
// Config precedence:
|
||||
//
|
||||
// * --kubeconfig flag pointing at a file
|
||||
//
|
||||
@@ -67,7 +84,7 @@ func GetConfig() (*rest.Config, error) {
|
||||
// It also applies saner defaults for QPS and burst based on the Kubernetes
|
||||
// controller manager defaults (20 QPS, 30 burst)
|
||||
//
|
||||
// Config precedence
|
||||
// Config precedence:
|
||||
//
|
||||
// * --kubeconfig flag pointing at a file
|
||||
//
|
||||
@@ -96,7 +113,7 @@ func GetConfigWithContext(context string) (*rest.Config, error) {
|
||||
var loadInClusterConfig = rest.InClusterConfig
|
||||
|
||||
// loadConfig loads a REST Config as per the rules specified in GetConfig.
|
||||
func loadConfig(context string) (*rest.Config, error) {
|
||||
func loadConfig(context string) (config *rest.Config, configErr error) {
|
||||
// If a flag is specified with the config location, use that
|
||||
if len(kubeconfig) > 0 {
|
||||
return loadConfigWithContext("", &clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfig}, context)
|
||||
@@ -106,9 +123,16 @@ func loadConfig(context string) (*rest.Config, error) {
|
||||
// try the in-cluster config.
|
||||
kubeconfigPath := os.Getenv(clientcmd.RecommendedConfigPathEnvVar)
|
||||
if len(kubeconfigPath) == 0 {
|
||||
if c, err := loadInClusterConfig(); err == nil {
|
||||
c, err := loadInClusterConfig()
|
||||
if err == nil {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if configErr != nil {
|
||||
log.Error(err, "unable to load in-cluster config")
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// If the recommended kubeconfig env variable is set, or there
|
||||
|
||||
11
vendor/sigs.k8s.io/controller-runtime/pkg/client/doc.go
generated
vendored
11
vendor/sigs.k8s.io/controller-runtime/pkg/client/doc.go
generated
vendored
@@ -17,7 +17,7 @@ limitations under the License.
|
||||
// Package client contains functionality for interacting with Kubernetes API
|
||||
// servers.
|
||||
//
|
||||
// Clients
|
||||
// # Clients
|
||||
//
|
||||
// Clients are split into two interfaces -- Readers and Writers. Readers
|
||||
// get and list, while writers create, update, and delete.
|
||||
@@ -25,18 +25,19 @@ limitations under the License.
|
||||
// The New function can be used to create a new client that talks directly
|
||||
// to the API server.
|
||||
//
|
||||
// A common pattern in Kubernetes to read from a cache and write to the API
|
||||
// It is a common pattern in Kubernetes to read from a cache and write to the API
|
||||
// server. This pattern is covered by the DelegatingClient type, which can
|
||||
// be used to have a client whose Reader is different from the Writer.
|
||||
//
|
||||
// Options
|
||||
// # Options
|
||||
//
|
||||
// Many client operations in Kubernetes support options. These options are
|
||||
// represented as variadic arguments at the end of a given method call.
|
||||
// For instance, to use a label selector on list, you can call
|
||||
// err := someReader.List(context.Background(), &podList, client.MatchingLabels{"somelabel": "someval"})
|
||||
//
|
||||
// Indexing
|
||||
// err := someReader.List(context.Background(), &podList, client.MatchingLabels{"somelabel": "someval"})
|
||||
//
|
||||
// # Indexing
|
||||
//
|
||||
// Indexes may be added to caches using a FieldIndexer. This allows you to easily
|
||||
// and efficiently look up objects with certain properties. You can then make
|
||||
|
||||
39
vendor/sigs.k8s.io/controller-runtime/pkg/client/dryrun.go
generated
vendored
39
vendor/sigs.k8s.io/controller-runtime/pkg/client/dryrun.go
generated
vendored
@@ -72,8 +72,8 @@ func (c *dryRunClient) Patch(ctx context.Context, obj Object, patch Patch, opts
|
||||
}
|
||||
|
||||
// Get implements client.Client.
|
||||
func (c *dryRunClient) Get(ctx context.Context, key ObjectKey, obj Object) error {
|
||||
return c.client.Get(ctx, key, obj)
|
||||
func (c *dryRunClient) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error {
|
||||
return c.client.Get(ctx, key, obj, opts...)
|
||||
}
|
||||
|
||||
// List implements client.Client.
|
||||
@@ -82,25 +82,38 @@ func (c *dryRunClient) List(ctx context.Context, obj ObjectList, opts ...ListOpt
|
||||
}
|
||||
|
||||
// Status implements client.StatusClient.
|
||||
func (c *dryRunClient) Status() StatusWriter {
|
||||
return &dryRunStatusWriter{client: c.client.Status()}
|
||||
func (c *dryRunClient) Status() SubResourceWriter {
|
||||
return c.SubResource("status")
|
||||
}
|
||||
|
||||
// ensure dryRunStatusWriter implements client.StatusWriter.
|
||||
var _ StatusWriter = &dryRunStatusWriter{}
|
||||
// SubResource implements client.SubResourceClient.
|
||||
func (c *dryRunClient) SubResource(subResource string) SubResourceClient {
|
||||
return &dryRunSubResourceClient{client: c.client.SubResource(subResource)}
|
||||
}
|
||||
|
||||
// dryRunStatusWriter is client.StatusWriter that writes status subresource with dryRun mode
|
||||
// ensure dryRunSubResourceWriter implements client.SubResourceWriter.
|
||||
var _ SubResourceWriter = &dryRunSubResourceClient{}
|
||||
|
||||
// dryRunSubResourceClient is client.SubResourceWriter that writes status subresource with dryRun mode
|
||||
// enforced.
|
||||
type dryRunStatusWriter struct {
|
||||
client StatusWriter
|
||||
type dryRunSubResourceClient struct {
|
||||
client SubResourceClient
|
||||
}
|
||||
|
||||
// Update implements client.StatusWriter.
|
||||
func (sw *dryRunStatusWriter) Update(ctx context.Context, obj Object, opts ...UpdateOption) error {
|
||||
func (sw *dryRunSubResourceClient) Get(ctx context.Context, obj, subResource Object, opts ...SubResourceGetOption) error {
|
||||
return sw.client.Get(ctx, obj, subResource, opts...)
|
||||
}
|
||||
|
||||
func (sw *dryRunSubResourceClient) Create(ctx context.Context, obj, subResource Object, opts ...SubResourceCreateOption) error {
|
||||
return sw.client.Create(ctx, obj, subResource, append(opts, DryRunAll)...)
|
||||
}
|
||||
|
||||
// Update implements client.SubResourceWriter.
|
||||
func (sw *dryRunSubResourceClient) Update(ctx context.Context, obj Object, opts ...SubResourceUpdateOption) error {
|
||||
return sw.client.Update(ctx, obj, append(opts, DryRunAll)...)
|
||||
}
|
||||
|
||||
// Patch implements client.StatusWriter.
|
||||
func (sw *dryRunStatusWriter) Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error {
|
||||
// Patch implements client.SubResourceWriter.
|
||||
func (sw *dryRunSubResourceClient) Patch(ctx context.Context, obj Object, patch Patch, opts ...SubResourcePatchOption) error {
|
||||
return sw.client.Patch(ctx, obj, patch, append(opts, DryRunAll)...)
|
||||
}
|
||||
|
||||
194
vendor/sigs.k8s.io/controller-runtime/pkg/client/fake/client.go
generated
vendored
194
vendor/sigs.k8s.io/controller-runtime/pkg/client/fake/client.go
generated
vendored
@@ -30,6 +30,8 @@ import (
|
||||
"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/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
utilrand "k8s.io/apimachinery/pkg/util/rand"
|
||||
@@ -37,6 +39,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/testing"
|
||||
"sigs.k8s.io/controller-runtime/pkg/internal/field/selector"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||
@@ -49,9 +52,14 @@ type versionedTracker struct {
|
||||
}
|
||||
|
||||
type fakeClient struct {
|
||||
tracker versionedTracker
|
||||
scheme *runtime.Scheme
|
||||
restMapper meta.RESTMapper
|
||||
tracker versionedTracker
|
||||
scheme *runtime.Scheme
|
||||
restMapper meta.RESTMapper
|
||||
|
||||
// indexes maps each GroupVersionKind (GVK) to the indexes registered for that GVK.
|
||||
// The inner map maps from index name to IndexerFunc.
|
||||
indexes map[schema.GroupVersionKind]map[string]client.IndexerFunc
|
||||
|
||||
schemeWriteLock sync.Mutex
|
||||
}
|
||||
|
||||
@@ -93,6 +101,10 @@ type ClientBuilder struct {
|
||||
initLists []client.ObjectList
|
||||
initRuntimeObjects []runtime.Object
|
||||
objectTracker testing.ObjectTracker
|
||||
|
||||
// indexes maps each GroupVersionKind (GVK) to the indexes registered for that GVK.
|
||||
// The inner map maps from index name to IndexerFunc.
|
||||
indexes map[schema.GroupVersionKind]map[string]client.IndexerFunc
|
||||
}
|
||||
|
||||
// WithScheme sets this builder's internal scheme.
|
||||
@@ -135,6 +147,44 @@ func (f *ClientBuilder) WithObjectTracker(ot testing.ObjectTracker) *ClientBuild
|
||||
return f
|
||||
}
|
||||
|
||||
// WithIndex can be optionally used to register an index with name `field` and indexer `extractValue`
|
||||
// for API objects of the same GroupVersionKind (GVK) as `obj` in the fake client.
|
||||
// It can be invoked multiple times, both with objects of the same GVK or different ones.
|
||||
// Invoking WithIndex twice with the same `field` and GVK (via `obj`) arguments will panic.
|
||||
// WithIndex retrieves the GVK of `obj` using the scheme registered via WithScheme if
|
||||
// WithScheme was previously invoked, the default scheme otherwise.
|
||||
func (f *ClientBuilder) WithIndex(obj runtime.Object, field string, extractValue client.IndexerFunc) *ClientBuilder {
|
||||
objScheme := f.scheme
|
||||
if objScheme == nil {
|
||||
objScheme = scheme.Scheme
|
||||
}
|
||||
|
||||
gvk, err := apiutil.GVKForObject(obj, objScheme)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// If this is the first index being registered, we initialize the map storing all the indexes.
|
||||
if f.indexes == nil {
|
||||
f.indexes = make(map[schema.GroupVersionKind]map[string]client.IndexerFunc)
|
||||
}
|
||||
|
||||
// If this is the first index being registered for the GroupVersionKind of `obj`, we initialize
|
||||
// the map storing the indexes for that GroupVersionKind.
|
||||
if f.indexes[gvk] == nil {
|
||||
f.indexes[gvk] = make(map[string]client.IndexerFunc)
|
||||
}
|
||||
|
||||
if _, fieldAlreadyIndexed := f.indexes[gvk][field]; fieldAlreadyIndexed {
|
||||
panic(fmt.Errorf("indexer conflict: field %s for GroupVersionKind %v is already indexed",
|
||||
field, gvk))
|
||||
}
|
||||
|
||||
f.indexes[gvk][field] = extractValue
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
// Build builds and returns a new fake client.
|
||||
func (f *ClientBuilder) Build() client.WithWatch {
|
||||
if f.scheme == nil {
|
||||
@@ -171,6 +221,7 @@ func (f *ClientBuilder) Build() client.WithWatch {
|
||||
tracker: tracker,
|
||||
scheme: f.scheme,
|
||||
restMapper: f.restMapper,
|
||||
indexes: f.indexes,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,7 +380,7 @@ func (t versionedTracker) Update(gvr schema.GroupVersionResource, obj runtime.Ob
|
||||
return t.ObjectTracker.Update(gvr, obj, ns)
|
||||
}
|
||||
|
||||
func (c *fakeClient) Get(ctx context.Context, key client.ObjectKey, obj client.Object) error {
|
||||
func (c *fakeClient) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error {
|
||||
gvr, err := getGVRFromObject(obj, c.scheme)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -420,21 +471,88 @@ func (c *fakeClient) List(ctx context.Context, obj client.ObjectList, opts ...cl
|
||||
return err
|
||||
}
|
||||
|
||||
if listOpts.LabelSelector != nil {
|
||||
objs, err := meta.ExtractList(obj)
|
||||
if listOpts.LabelSelector == nil && listOpts.FieldSelector == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// If we're here, either a label or field selector are specified (or both), so before we return
|
||||
// the list we must filter it. If both selectors are set, they are ANDed.
|
||||
objs, err := meta.ExtractList(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
filteredList, err := c.filterList(objs, gvk, listOpts.LabelSelector, listOpts.FieldSelector)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return meta.SetList(obj, filteredList)
|
||||
}
|
||||
|
||||
func (c *fakeClient) filterList(list []runtime.Object, gvk schema.GroupVersionKind, ls labels.Selector, fs fields.Selector) ([]runtime.Object, error) {
|
||||
// Filter the objects with the label selector
|
||||
filteredList := list
|
||||
if ls != nil {
|
||||
objsFilteredByLabel, err := objectutil.FilterWithLabels(list, ls)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
filteredObjs, err := objectutil.FilterWithLabels(objs, listOpts.LabelSelector)
|
||||
filteredList = objsFilteredByLabel
|
||||
}
|
||||
|
||||
// Filter the result of the previous pass with the field selector
|
||||
if fs != nil {
|
||||
objsFilteredByField, err := c.filterWithFields(filteredList, gvk, fs)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
err = meta.SetList(obj, filteredObjs)
|
||||
if err != nil {
|
||||
return err
|
||||
filteredList = objsFilteredByField
|
||||
}
|
||||
|
||||
return filteredList, nil
|
||||
}
|
||||
|
||||
func (c *fakeClient) filterWithFields(list []runtime.Object, gvk schema.GroupVersionKind, fs fields.Selector) ([]runtime.Object, error) {
|
||||
// We only allow filtering on the basis of a single field to ensure consistency with the
|
||||
// behavior of the cache reader (which we're faking here).
|
||||
fieldKey, fieldVal, requiresExact := selector.RequiresExactMatch(fs)
|
||||
if !requiresExact {
|
||||
return nil, fmt.Errorf("field selector %s is not in one of the two supported forms \"key==val\" or \"key=val\"",
|
||||
fs)
|
||||
}
|
||||
|
||||
// Field selection is mimicked via indexes, so there's no sane answer this function can give
|
||||
// if there are no indexes registered for the GroupVersionKind of the objects in the list.
|
||||
indexes := c.indexes[gvk]
|
||||
if len(indexes) == 0 || indexes[fieldKey] == nil {
|
||||
return nil, fmt.Errorf("List on GroupVersionKind %v specifies selector on field %s, but no "+
|
||||
"index with name %s has been registered for GroupVersionKind %v", gvk, fieldKey, fieldKey, gvk)
|
||||
}
|
||||
|
||||
indexExtractor := indexes[fieldKey]
|
||||
filteredList := make([]runtime.Object, 0, len(list))
|
||||
for _, obj := range list {
|
||||
if c.objMatchesFieldSelector(obj, indexExtractor, fieldVal) {
|
||||
filteredList = append(filteredList, obj)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return filteredList, nil
|
||||
}
|
||||
|
||||
func (c *fakeClient) objMatchesFieldSelector(o runtime.Object, extractIndex client.IndexerFunc, val string) bool {
|
||||
obj, isClientObject := o.(client.Object)
|
||||
if !isClientObject {
|
||||
panic(fmt.Errorf("expected object %v to be of type client.Object, but it's not", o))
|
||||
}
|
||||
|
||||
for _, extractedVal := range extractIndex(obj) {
|
||||
if extractedVal == val {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *fakeClient) Scheme() *runtime.Scheme {
|
||||
@@ -634,8 +752,12 @@ func (c *fakeClient) Patch(ctx context.Context, obj client.Object, patch client.
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *fakeClient) Status() client.StatusWriter {
|
||||
return &fakeStatusWriter{client: c}
|
||||
func (c *fakeClient) Status() client.SubResourceWriter {
|
||||
return c.SubResource("status")
|
||||
}
|
||||
|
||||
func (c *fakeClient) SubResource(subResource string) client.SubResourceClient {
|
||||
return &fakeSubResourceClient{client: c}
|
||||
}
|
||||
|
||||
func (c *fakeClient) deleteObject(gvr schema.GroupVersionResource, accessor metav1.Object) error {
|
||||
@@ -664,20 +786,44 @@ func getGVRFromObject(obj runtime.Object, scheme *runtime.Scheme) (schema.GroupV
|
||||
return gvr, nil
|
||||
}
|
||||
|
||||
type fakeStatusWriter struct {
|
||||
type fakeSubResourceClient struct {
|
||||
client *fakeClient
|
||||
}
|
||||
|
||||
func (sw *fakeStatusWriter) Update(ctx context.Context, obj client.Object, opts ...client.UpdateOption) error {
|
||||
// TODO(droot): This results in full update of the obj (spec + status). Need
|
||||
// a way to update status field only.
|
||||
return sw.client.Update(ctx, obj, opts...)
|
||||
func (sw *fakeSubResourceClient) Get(ctx context.Context, obj, subResource client.Object, opts ...client.SubResourceGetOption) error {
|
||||
panic("fakeSubResourceClient does not support get")
|
||||
}
|
||||
|
||||
func (sw *fakeStatusWriter) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.PatchOption) error {
|
||||
// TODO(droot): This results in full update of the obj (spec + status). Need
|
||||
// a way to update status field only.
|
||||
return sw.client.Patch(ctx, obj, patch, opts...)
|
||||
func (sw *fakeSubResourceClient) Create(ctx context.Context, obj client.Object, subResource client.Object, opts ...client.SubResourceCreateOption) error {
|
||||
panic("fakeSubResourceWriter does not support create")
|
||||
}
|
||||
|
||||
func (sw *fakeSubResourceClient) Update(ctx context.Context, obj client.Object, opts ...client.SubResourceUpdateOption) error {
|
||||
// TODO(droot): This results in full update of the obj (spec + subresources). Need
|
||||
// a way to update subresource only.
|
||||
updateOptions := client.SubResourceUpdateOptions{}
|
||||
updateOptions.ApplyOptions(opts)
|
||||
|
||||
body := obj
|
||||
if updateOptions.SubResourceBody != nil {
|
||||
body = updateOptions.SubResourceBody
|
||||
}
|
||||
return sw.client.Update(ctx, body, &updateOptions.UpdateOptions)
|
||||
}
|
||||
|
||||
func (sw *fakeSubResourceClient) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error {
|
||||
// TODO(droot): This results in full update of the obj (spec + subresources). Need
|
||||
// a way to update subresource only.
|
||||
|
||||
patchOptions := client.SubResourcePatchOptions{}
|
||||
patchOptions.ApplyOptions(opts)
|
||||
|
||||
body := obj
|
||||
if patchOptions.SubResourceBody != nil {
|
||||
body = patchOptions.SubResourceBody
|
||||
}
|
||||
|
||||
return sw.client.Patch(ctx, body, patch, &patchOptions.PatchOptions)
|
||||
}
|
||||
|
||||
func allowsUnconditionalUpdate(gvk schema.GroupVersionKind) bool {
|
||||
|
||||
13
vendor/sigs.k8s.io/controller-runtime/pkg/client/fake/doc.go
generated
vendored
13
vendor/sigs.k8s.io/controller-runtime/pkg/client/fake/doc.go
generated
vendored
@@ -28,12 +28,11 @@ When in doubt, it's almost always better not to use this package and instead use
|
||||
envtest.Environment with a real client and API server.
|
||||
|
||||
WARNING: ⚠️ Current Limitations / Known Issues with the fake Client ⚠️
|
||||
- This client does not have a way to inject specific errors to test handled vs. unhandled errors.
|
||||
- There is some support for sub resources which can cause issues with tests if you're trying to update
|
||||
e.g. metadata and status in the same reconcile.
|
||||
- No OpeanAPI validation is performed when creating or updating objects.
|
||||
- ObjectMeta's `Generation` and `ResourceVersion` don't behave properly, Patch or Update
|
||||
operations that rely on these fields will fail, or give false positives.
|
||||
|
||||
- This client does not have a way to inject specific errors to test handled vs. unhandled errors.
|
||||
- There is some support for sub resources which can cause issues with tests if you're trying to update
|
||||
e.g. metadata and status in the same reconcile.
|
||||
- No OpenAPI validation is performed when creating or updating objects.
|
||||
- ObjectMeta's `Generation` and `ResourceVersion` don't behave properly, Patch or Update
|
||||
operations that rely on these fields will fail, or give false positives.
|
||||
*/
|
||||
package fake
|
||||
|
||||
86
vendor/sigs.k8s.io/controller-runtime/pkg/client/interfaces.go
generated
vendored
86
vendor/sigs.k8s.io/controller-runtime/pkg/client/interfaces.go
generated
vendored
@@ -50,7 +50,7 @@ type Reader interface {
|
||||
// Get retrieves an obj for the given object key from the Kubernetes Cluster.
|
||||
// obj must be a struct pointer so that obj can be updated with the response
|
||||
// returned by the Server.
|
||||
Get(ctx context.Context, key ObjectKey, obj Object) error
|
||||
Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error
|
||||
|
||||
// List retrieves list of objects for a given namespace and list options. On a
|
||||
// successful call, Items field in the list will be populated with the
|
||||
@@ -60,7 +60,8 @@ type Reader interface {
|
||||
|
||||
// Writer knows how to create, delete, and update Kubernetes objects.
|
||||
type Writer interface {
|
||||
// Create saves the object obj in the Kubernetes cluster.
|
||||
// Create saves the object obj in the Kubernetes cluster. obj must be a
|
||||
// struct pointer so that obj can be updated with the content returned by the Server.
|
||||
Create(ctx context.Context, obj Object, opts ...CreateOption) error
|
||||
|
||||
// Delete deletes the given obj from Kubernetes cluster.
|
||||
@@ -81,20 +82,80 @@ type Writer interface {
|
||||
// StatusClient knows how to create a client which can update status subresource
|
||||
// for kubernetes objects.
|
||||
type StatusClient interface {
|
||||
Status() StatusWriter
|
||||
Status() SubResourceWriter
|
||||
}
|
||||
|
||||
// StatusWriter knows how to update status subresource of a Kubernetes object.
|
||||
type StatusWriter interface {
|
||||
// SubResourceClientConstructor knows how to create a client which can update subresource
|
||||
// for kubernetes objects.
|
||||
type SubResourceClientConstructor interface {
|
||||
// SubResourceClientConstructor returns a subresource client for the named subResource. Known
|
||||
// upstream subResources usages are:
|
||||
// - ServiceAccount token creation:
|
||||
// sa := &corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}}
|
||||
// token := &authenticationv1.TokenRequest{}
|
||||
// c.SubResourceClient("token").Create(ctx, sa, token)
|
||||
//
|
||||
// - Pod eviction creation:
|
||||
// pod := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}}
|
||||
// c.SubResourceClient("eviction").Create(ctx, pod, &policyv1.Eviction{})
|
||||
//
|
||||
// - Pod binding creation:
|
||||
// pod := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}}
|
||||
// binding := &corev1.Binding{Target: corev1.ObjectReference{Name: "my-node"}}
|
||||
// c.SubResourceClient("binding").Create(ctx, pod, binding)
|
||||
//
|
||||
// - CertificateSigningRequest approval:
|
||||
// csr := &certificatesv1.CertificateSigningRequest{
|
||||
// ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"},
|
||||
// Status: certificatesv1.CertificateSigningRequestStatus{
|
||||
// Conditions: []certificatesv1.[]CertificateSigningRequestCondition{{
|
||||
// Type: certificatesv1.CertificateApproved,
|
||||
// Status: corev1.ConditionTrue,
|
||||
// }},
|
||||
// },
|
||||
// }
|
||||
// c.SubResourceClient("approval").Update(ctx, csr)
|
||||
//
|
||||
// - Scale retrieval:
|
||||
// dep := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}}
|
||||
// scale := &autoscalingv1.Scale{}
|
||||
// c.SubResourceClient("scale").Get(ctx, dep, scale)
|
||||
//
|
||||
// - Scale update:
|
||||
// dep := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}}
|
||||
// scale := &autoscalingv1.Scale{Spec: autoscalingv1.ScaleSpec{Replicas: 2}}
|
||||
// c.SubResourceClient("scale").Update(ctx, dep, client.WithSubResourceBody(scale))
|
||||
SubResource(subResource string) SubResourceClient
|
||||
}
|
||||
|
||||
// StatusWriter is kept for backward compatibility.
|
||||
type StatusWriter = SubResourceWriter
|
||||
|
||||
// SubResourceReader knows how to read SubResources
|
||||
type SubResourceReader interface {
|
||||
Get(ctx context.Context, obj Object, subResource Object, opts ...SubResourceGetOption) error
|
||||
}
|
||||
|
||||
// SubResourceWriter knows how to update subresource of a Kubernetes object.
|
||||
type SubResourceWriter interface {
|
||||
// Create saves the subResource object in the Kubernetes cluster. obj must be a
|
||||
// struct pointer so that obj can be updated with the content returned by the Server.
|
||||
Create(ctx context.Context, obj Object, subResource Object, opts ...SubResourceCreateOption) error
|
||||
// Update updates the fields corresponding to the status subresource for the
|
||||
// given obj. obj must be a struct pointer so that obj can be updated
|
||||
// with the content returned by the Server.
|
||||
Update(ctx context.Context, obj Object, opts ...UpdateOption) error
|
||||
Update(ctx context.Context, obj Object, opts ...SubResourceUpdateOption) error
|
||||
|
||||
// Patch patches the given object's subresource. obj must be a struct
|
||||
// pointer so that obj can be updated with the content returned by the
|
||||
// Server.
|
||||
Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error
|
||||
Patch(ctx context.Context, obj Object, patch Patch, opts ...SubResourcePatchOption) error
|
||||
}
|
||||
|
||||
// SubResourceClient knows how to perform CRU operations on Kubernetes objects.
|
||||
type SubResourceClient interface {
|
||||
SubResourceReader
|
||||
SubResourceWriter
|
||||
}
|
||||
|
||||
// Client knows how to perform CRUD operations on Kubernetes objects.
|
||||
@@ -102,6 +163,7 @@ type Client interface {
|
||||
Reader
|
||||
Writer
|
||||
StatusClient
|
||||
SubResourceClientConstructor
|
||||
|
||||
// Scheme returns the scheme this client is using.
|
||||
Scheme() *runtime.Scheme
|
||||
@@ -143,3 +205,13 @@ func IgnoreNotFound(err error) error {
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// IgnoreAlreadyExists returns nil on AlreadyExists errors.
|
||||
// All other values that are not AlreadyExists errors or nil are returned unmodified.
|
||||
func IgnoreAlreadyExists(err error) error {
|
||||
if apierrors.IsAlreadyExists(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
23
vendor/sigs.k8s.io/controller-runtime/pkg/client/metadata_client.go
generated
vendored
23
vendor/sigs.k8s.io/controller-runtime/pkg/client/metadata_client.go
generated
vendored
@@ -116,7 +116,7 @@ func (mc *metadataClient) Patch(ctx context.Context, obj Object, patch Patch, op
|
||||
}
|
||||
|
||||
// Get implements client.Client.
|
||||
func (mc *metadataClient) Get(ctx context.Context, key ObjectKey, obj Object) error {
|
||||
func (mc *metadataClient) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error {
|
||||
metadata, ok := obj.(*metav1.PartialObjectMetadata)
|
||||
if !ok {
|
||||
return fmt.Errorf("metadata client did not understand object: %T", obj)
|
||||
@@ -124,12 +124,15 @@ func (mc *metadataClient) Get(ctx context.Context, key ObjectKey, obj Object) er
|
||||
|
||||
gvk := metadata.GroupVersionKind()
|
||||
|
||||
getOpts := GetOptions{}
|
||||
getOpts.ApplyOptions(opts)
|
||||
|
||||
resInt, err := mc.getResourceInterface(gvk, key.Namespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := resInt.Get(ctx, key.Name, metav1.GetOptions{})
|
||||
res, err := resInt.Get(ctx, key.Name, *getOpts.AsGetOptions())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -165,7 +168,7 @@ func (mc *metadataClient) List(ctx context.Context, obj ObjectList, opts ...List
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mc *metadataClient) PatchStatus(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error {
|
||||
func (mc *metadataClient) PatchSubResource(ctx context.Context, obj Object, subResource string, patch Patch, opts ...SubResourcePatchOption) error {
|
||||
metadata, ok := obj.(*metav1.PartialObjectMetadata)
|
||||
if !ok {
|
||||
return fmt.Errorf("metadata client did not understand object: %T", obj)
|
||||
@@ -177,16 +180,24 @@ func (mc *metadataClient) PatchStatus(ctx context.Context, obj Object, patch Pat
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := patch.Data(obj)
|
||||
patchOpts := &SubResourcePatchOptions{}
|
||||
patchOpts.ApplyOptions(opts)
|
||||
|
||||
body := obj
|
||||
if patchOpts.SubResourceBody != nil {
|
||||
body = patchOpts.SubResourceBody
|
||||
}
|
||||
|
||||
data, err := patch.Data(body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
patchOpts := &PatchOptions{}
|
||||
res, err := resInt.Patch(ctx, metadata.Name, patch.Type(), data, *patchOpts.AsPatchOptions(), "status")
|
||||
res, err := resInt.Patch(ctx, metadata.Name, patch.Type(), data, *patchOpts.AsPatchOptions(), subResource)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*metadata = *res
|
||||
metadata.SetGroupVersionKind(gvk) // restore the GVK, which isn't set on metadata
|
||||
return nil
|
||||
|
||||
104
vendor/sigs.k8s.io/controller-runtime/pkg/client/namespaced_client.go
generated
vendored
104
vendor/sigs.k8s.io/controller-runtime/pkg/client/namespaced_client.go
generated
vendored
@@ -52,7 +52,7 @@ func (n *namespacedClient) RESTMapper() meta.RESTMapper {
|
||||
return n.client.RESTMapper()
|
||||
}
|
||||
|
||||
// Create implements clinet.Client.
|
||||
// Create implements client.Client.
|
||||
func (n *namespacedClient) Create(ctx context.Context, obj Object, opts ...CreateOption) error {
|
||||
isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, n.Scheme(), n.RESTMapper())
|
||||
if err != nil {
|
||||
@@ -138,18 +138,18 @@ func (n *namespacedClient) Patch(ctx context.Context, obj Object, patch Patch, o
|
||||
}
|
||||
|
||||
// Get implements client.Client.
|
||||
func (n *namespacedClient) Get(ctx context.Context, key ObjectKey, obj Object) error {
|
||||
func (n *namespacedClient) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error {
|
||||
isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, n.Scheme(), n.RESTMapper())
|
||||
if err != nil {
|
||||
return fmt.Errorf("error finding the scope of the object: %w", err)
|
||||
}
|
||||
if isNamespaceScoped {
|
||||
if key.Namespace != "" && key.Namespace != n.namespace {
|
||||
return fmt.Errorf("namespace %s provided for the object %s does not match the namesapce %s on the client", key.Namespace, obj.GetName(), n.namespace)
|
||||
return fmt.Errorf("namespace %s provided for the object %s does not match the namespace %s on the client", key.Namespace, obj.GetName(), n.namespace)
|
||||
}
|
||||
key.Namespace = n.namespace
|
||||
}
|
||||
return n.client.Get(ctx, key, obj)
|
||||
return n.client.Get(ctx, key, obj, opts...)
|
||||
}
|
||||
|
||||
// List implements client.Client.
|
||||
@@ -161,21 +161,80 @@ func (n *namespacedClient) List(ctx context.Context, obj ObjectList, opts ...Lis
|
||||
}
|
||||
|
||||
// Status implements client.StatusClient.
|
||||
func (n *namespacedClient) Status() StatusWriter {
|
||||
return &namespacedClientStatusWriter{StatusClient: n.client.Status(), namespace: n.namespace, namespacedclient: n}
|
||||
func (n *namespacedClient) Status() SubResourceWriter {
|
||||
return n.SubResource("status")
|
||||
}
|
||||
|
||||
// ensure namespacedClientStatusWriter implements client.StatusWriter.
|
||||
var _ StatusWriter = &namespacedClientStatusWriter{}
|
||||
// SubResource implements client.SubResourceClient.
|
||||
func (n *namespacedClient) SubResource(subResource string) SubResourceClient {
|
||||
return &namespacedClientSubResourceClient{client: n.client.SubResource(subResource), namespace: n.namespace, namespacedclient: n}
|
||||
}
|
||||
|
||||
type namespacedClientStatusWriter struct {
|
||||
StatusClient StatusWriter
|
||||
// ensure namespacedClientSubResourceClient implements client.SubResourceClient.
|
||||
var _ SubResourceClient = &namespacedClientSubResourceClient{}
|
||||
|
||||
type namespacedClientSubResourceClient struct {
|
||||
client SubResourceClient
|
||||
namespace string
|
||||
namespacedclient Client
|
||||
}
|
||||
|
||||
// Update implements client.StatusWriter.
|
||||
func (nsw *namespacedClientStatusWriter) Update(ctx context.Context, obj Object, opts ...UpdateOption) error {
|
||||
func (nsw *namespacedClientSubResourceClient) Get(ctx context.Context, obj, subResource Object, opts ...SubResourceGetOption) error {
|
||||
isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, nsw.namespacedclient.Scheme(), nsw.namespacedclient.RESTMapper())
|
||||
if err != nil {
|
||||
return fmt.Errorf("error finding the scope of the object: %w", err)
|
||||
}
|
||||
|
||||
objectNamespace := obj.GetNamespace()
|
||||
if objectNamespace != nsw.namespace && objectNamespace != "" {
|
||||
return fmt.Errorf("namespace %s of the object %s does not match the namespace %s on the client", objectNamespace, obj.GetName(), nsw.namespace)
|
||||
}
|
||||
|
||||
if isNamespaceScoped && objectNamespace == "" {
|
||||
obj.SetNamespace(nsw.namespace)
|
||||
}
|
||||
|
||||
return nsw.client.Get(ctx, obj, subResource, opts...)
|
||||
}
|
||||
|
||||
func (nsw *namespacedClientSubResourceClient) Create(ctx context.Context, obj, subResource Object, opts ...SubResourceCreateOption) error {
|
||||
isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, nsw.namespacedclient.Scheme(), nsw.namespacedclient.RESTMapper())
|
||||
if err != nil {
|
||||
return fmt.Errorf("error finding the scope of the object: %w", err)
|
||||
}
|
||||
|
||||
objectNamespace := obj.GetNamespace()
|
||||
if objectNamespace != nsw.namespace && objectNamespace != "" {
|
||||
return fmt.Errorf("namespace %s of the object %s does not match the namespace %s on the client", objectNamespace, obj.GetName(), nsw.namespace)
|
||||
}
|
||||
|
||||
if isNamespaceScoped && objectNamespace == "" {
|
||||
obj.SetNamespace(nsw.namespace)
|
||||
}
|
||||
|
||||
return nsw.client.Create(ctx, obj, subResource, opts...)
|
||||
}
|
||||
|
||||
// Update implements client.SubResourceWriter.
|
||||
func (nsw *namespacedClientSubResourceClient) Update(ctx context.Context, obj Object, opts ...SubResourceUpdateOption) error {
|
||||
isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, nsw.namespacedclient.Scheme(), nsw.namespacedclient.RESTMapper())
|
||||
if err != nil {
|
||||
return fmt.Errorf("error finding the scope of the object: %w", err)
|
||||
}
|
||||
|
||||
objectNamespace := obj.GetNamespace()
|
||||
if objectNamespace != nsw.namespace && objectNamespace != "" {
|
||||
return fmt.Errorf("namespace %s of the object %s does not match the namespace %s on the client", objectNamespace, obj.GetName(), nsw.namespace)
|
||||
}
|
||||
|
||||
if isNamespaceScoped && objectNamespace == "" {
|
||||
obj.SetNamespace(nsw.namespace)
|
||||
}
|
||||
return nsw.client.Update(ctx, obj, opts...)
|
||||
}
|
||||
|
||||
// Patch implements client.SubResourceWriter.
|
||||
func (nsw *namespacedClientSubResourceClient) Patch(ctx context.Context, obj Object, patch Patch, opts ...SubResourcePatchOption) error {
|
||||
isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, nsw.namespacedclient.Scheme(), nsw.namespacedclient.RESTMapper())
|
||||
|
||||
if err != nil {
|
||||
@@ -190,24 +249,5 @@ func (nsw *namespacedClientStatusWriter) Update(ctx context.Context, obj Object,
|
||||
if isNamespaceScoped && objectNamespace == "" {
|
||||
obj.SetNamespace(nsw.namespace)
|
||||
}
|
||||
return nsw.StatusClient.Update(ctx, obj, opts...)
|
||||
}
|
||||
|
||||
// Patch implements client.StatusWriter.
|
||||
func (nsw *namespacedClientStatusWriter) Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error {
|
||||
isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, nsw.namespacedclient.Scheme(), nsw.namespacedclient.RESTMapper())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("error finding the scope of the object: %w", err)
|
||||
}
|
||||
|
||||
objectNamespace := obj.GetNamespace()
|
||||
if objectNamespace != nsw.namespace && objectNamespace != "" {
|
||||
return fmt.Errorf("namespace %s of the object %s does not match the namespace %s on the client", objectNamespace, obj.GetName(), nsw.namespace)
|
||||
}
|
||||
|
||||
if isNamespaceScoped && objectNamespace == "" {
|
||||
obj.SetNamespace(nsw.namespace)
|
||||
}
|
||||
return nsw.StatusClient.Patch(ctx, obj, patch, opts...)
|
||||
return nsw.client.Patch(ctx, obj, patch, opts...)
|
||||
}
|
||||
|
||||
124
vendor/sigs.k8s.io/controller-runtime/pkg/client/options.go
generated
vendored
124
vendor/sigs.k8s.io/controller-runtime/pkg/client/options.go
generated
vendored
@@ -37,6 +37,12 @@ type DeleteOption interface {
|
||||
ApplyToDelete(*DeleteOptions)
|
||||
}
|
||||
|
||||
// GetOption is some configuration that modifies options for a get request.
|
||||
type GetOption interface {
|
||||
// ApplyToGet applies this configuration to the given get options.
|
||||
ApplyToGet(*GetOptions)
|
||||
}
|
||||
|
||||
// ListOption is some configuration that modifies options for a list request.
|
||||
type ListOption interface {
|
||||
// ApplyToList applies this configuration to the given list options.
|
||||
@@ -61,6 +67,29 @@ type DeleteAllOfOption interface {
|
||||
ApplyToDeleteAllOf(*DeleteAllOfOptions)
|
||||
}
|
||||
|
||||
// SubResourceGetOption modifies options for a SubResource Get request.
|
||||
type SubResourceGetOption interface {
|
||||
ApplyToSubResourceGet(*SubResourceGetOptions)
|
||||
}
|
||||
|
||||
// SubResourceUpdateOption is some configuration that modifies options for a update request.
|
||||
type SubResourceUpdateOption interface {
|
||||
// ApplyToSubResourceUpdate applies this configuration to the given update options.
|
||||
ApplyToSubResourceUpdate(*SubResourceUpdateOptions)
|
||||
}
|
||||
|
||||
// SubResourceCreateOption is some configuration that modifies options for a create request.
|
||||
type SubResourceCreateOption interface {
|
||||
// ApplyToSubResourceCreate applies this configuration to the given create options.
|
||||
ApplyToSubResourceCreate(*SubResourceCreateOptions)
|
||||
}
|
||||
|
||||
// SubResourcePatchOption configures a subresource patch request.
|
||||
type SubResourcePatchOption interface {
|
||||
// ApplyToSubResourcePatch applies the configuration on the given patch options.
|
||||
ApplyToSubResourcePatch(*SubResourcePatchOptions)
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ Multi-Type Options
|
||||
@@ -90,10 +119,23 @@ func (dryRunAll) ApplyToPatch(opts *PatchOptions) {
|
||||
func (dryRunAll) ApplyToDelete(opts *DeleteOptions) {
|
||||
opts.DryRun = []string{metav1.DryRunAll}
|
||||
}
|
||||
|
||||
func (dryRunAll) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) {
|
||||
opts.DryRun = []string{metav1.DryRunAll}
|
||||
}
|
||||
|
||||
func (dryRunAll) ApplyToSubResourceCreate(opts *SubResourceCreateOptions) {
|
||||
opts.DryRun = []string{metav1.DryRunAll}
|
||||
}
|
||||
|
||||
func (dryRunAll) ApplyToSubResourceUpdate(opts *SubResourceUpdateOptions) {
|
||||
opts.DryRun = []string{metav1.DryRunAll}
|
||||
}
|
||||
|
||||
func (dryRunAll) ApplyToSubResourcePatch(opts *SubResourcePatchOptions) {
|
||||
opts.DryRun = []string{metav1.DryRunAll}
|
||||
}
|
||||
|
||||
// FieldOwner set the field manager name for the given server-side apply patch.
|
||||
type FieldOwner string
|
||||
|
||||
@@ -112,6 +154,21 @@ func (f FieldOwner) ApplyToUpdate(opts *UpdateOptions) {
|
||||
opts.FieldManager = string(f)
|
||||
}
|
||||
|
||||
// ApplyToSubResourcePatch applies this configuration to the given patch options.
|
||||
func (f FieldOwner) ApplyToSubResourcePatch(opts *SubResourcePatchOptions) {
|
||||
opts.FieldManager = string(f)
|
||||
}
|
||||
|
||||
// ApplyToSubResourceCreate applies this configuration to the given create options.
|
||||
func (f FieldOwner) ApplyToSubResourceCreate(opts *SubResourceCreateOptions) {
|
||||
opts.FieldManager = string(f)
|
||||
}
|
||||
|
||||
// ApplyToSubResourceUpdate applies this configuration to the given update options.
|
||||
func (f FieldOwner) ApplyToSubResourceUpdate(opts *SubResourceUpdateOptions) {
|
||||
opts.FieldManager = string(f)
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ Create Options
|
||||
@@ -311,6 +368,45 @@ func (p PropagationPolicy) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) {
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ Get Options
|
||||
|
||||
// GetOptions contains options for get operation.
|
||||
// Now it only has a Raw field, with support for specific resourceVersion.
|
||||
type GetOptions struct {
|
||||
// Raw represents raw GetOptions, as passed to the API server. Note
|
||||
// that these may not be respected by all implementations of interface.
|
||||
Raw *metav1.GetOptions
|
||||
}
|
||||
|
||||
var _ GetOption = &GetOptions{}
|
||||
|
||||
// ApplyToGet implements GetOption for GetOptions.
|
||||
func (o *GetOptions) ApplyToGet(lo *GetOptions) {
|
||||
if o.Raw != nil {
|
||||
lo.Raw = o.Raw
|
||||
}
|
||||
}
|
||||
|
||||
// AsGetOptions returns these options as a flattened metav1.GetOptions.
|
||||
// This may mutate the Raw field.
|
||||
func (o *GetOptions) AsGetOptions() *metav1.GetOptions {
|
||||
if o == nil || o.Raw == nil {
|
||||
return &metav1.GetOptions{}
|
||||
}
|
||||
return o.Raw
|
||||
}
|
||||
|
||||
// ApplyOptions applies the given get options on these options,
|
||||
// and then returns itself (for convenient chaining).
|
||||
func (o *GetOptions) ApplyOptions(opts []GetOption) *GetOptions {
|
||||
for _, opt := range opts {
|
||||
opt.ApplyToGet(o)
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ List Options
|
||||
|
||||
// ListOptions contains options for limiting or filtering results.
|
||||
@@ -341,6 +437,12 @@ type ListOptions struct {
|
||||
// it has expired. This field is not supported if watch is true in the Raw ListOptions.
|
||||
Continue string
|
||||
|
||||
// UnsafeDisableDeepCopy indicates not to deep copy objects during list objects.
|
||||
// Be very careful with this, when enabled you must DeepCopy any object before mutating it,
|
||||
// otherwise you will mutate the object in the cache.
|
||||
// +optional
|
||||
UnsafeDisableDeepCopy *bool
|
||||
|
||||
// Raw represents raw ListOptions, as passed to the API server. Note
|
||||
// that these may not be respected by all implementations of interface,
|
||||
// and the LabelSelector, FieldSelector, Limit and Continue fields are ignored.
|
||||
@@ -369,6 +471,9 @@ func (o *ListOptions) ApplyToList(lo *ListOptions) {
|
||||
if o.Continue != "" {
|
||||
lo.Continue = o.Continue
|
||||
}
|
||||
if o.UnsafeDisableDeepCopy != nil {
|
||||
lo.UnsafeDisableDeepCopy = o.UnsafeDisableDeepCopy
|
||||
}
|
||||
}
|
||||
|
||||
// AsListOptions returns these options as a flattened metav1.ListOptions.
|
||||
@@ -511,6 +616,25 @@ func (l Limit) ApplyToList(opts *ListOptions) {
|
||||
opts.Limit = int64(l)
|
||||
}
|
||||
|
||||
// UnsafeDisableDeepCopyOption indicates not to deep copy objects during list objects.
|
||||
// Be very careful with this, when enabled you must DeepCopy any object before mutating it,
|
||||
// otherwise you will mutate the object in the cache.
|
||||
type UnsafeDisableDeepCopyOption bool
|
||||
|
||||
// ApplyToList applies this configuration to the given an List options.
|
||||
func (d UnsafeDisableDeepCopyOption) ApplyToList(opts *ListOptions) {
|
||||
definitelyTrue := true
|
||||
definitelyFalse := false
|
||||
if d {
|
||||
opts.UnsafeDisableDeepCopy = &definitelyTrue
|
||||
} else {
|
||||
opts.UnsafeDisableDeepCopy = &definitelyFalse
|
||||
}
|
||||
}
|
||||
|
||||
// UnsafeDisableDeepCopy indicates not to deep copy objects during list objects.
|
||||
const UnsafeDisableDeepCopy = UnsafeDisableDeepCopyOption(true)
|
||||
|
||||
// Continue sets a continuation token to retrieve chunks of results when using limit.
|
||||
// Continue does not implement DeleteAllOfOption interface because the server
|
||||
// does not support setting it for deletecollection operations.
|
||||
|
||||
2
vendor/sigs.k8s.io/controller-runtime/pkg/client/patch.go
generated
vendored
2
vendor/sigs.k8s.io/controller-runtime/pkg/client/patch.go
generated
vendored
@@ -19,7 +19,7 @@ package client
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
jsonpatch "github.com/evanphx/json-patch"
|
||||
jsonpatch "github.com/evanphx/json-patch/v5"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/json"
|
||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
|
||||
12
vendor/sigs.k8s.io/controller-runtime/pkg/client/split.go
generated
vendored
12
vendor/sigs.k8s.io/controller-runtime/pkg/client/split.go
generated
vendored
@@ -61,8 +61,9 @@ func NewDelegatingClient(in NewDelegatingClientInput) (Client, error) {
|
||||
uncachedGVKs: uncachedGVKs,
|
||||
cacheUnstructured: in.CacheUnstructured,
|
||||
},
|
||||
Writer: in.Client,
|
||||
StatusClient: in.Client,
|
||||
Writer: in.Client,
|
||||
StatusClient: in.Client,
|
||||
SubResourceClientConstructor: in.Client,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -70,6 +71,7 @@ type delegatingClient struct {
|
||||
Reader
|
||||
Writer
|
||||
StatusClient
|
||||
SubResourceClientConstructor
|
||||
|
||||
scheme *runtime.Scheme
|
||||
mapper meta.RESTMapper
|
||||
@@ -121,13 +123,13 @@ func (d *delegatingReader) shouldBypassCache(obj runtime.Object) (bool, error) {
|
||||
}
|
||||
|
||||
// Get retrieves an obj for a given object key from the Kubernetes Cluster.
|
||||
func (d *delegatingReader) Get(ctx context.Context, key ObjectKey, obj Object) error {
|
||||
func (d *delegatingReader) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error {
|
||||
if isUncached, err := d.shouldBypassCache(obj); err != nil {
|
||||
return err
|
||||
} else if isUncached {
|
||||
return d.ClientReader.Get(ctx, key, obj)
|
||||
return d.ClientReader.Get(ctx, key, obj, opts...)
|
||||
}
|
||||
return d.CacheReader.Get(ctx, key, obj)
|
||||
return d.CacheReader.Get(ctx, key, obj, opts...)
|
||||
}
|
||||
|
||||
// List retrieves list of objects for a given namespace and list options.
|
||||
|
||||
108
vendor/sigs.k8s.io/controller-runtime/pkg/client/typed_client.go
generated
vendored
108
vendor/sigs.k8s.io/controller-runtime/pkg/client/typed_client.go
generated
vendored
@@ -24,7 +24,6 @@ import (
|
||||
|
||||
var _ Reader = &typedClient{}
|
||||
var _ Writer = &typedClient{}
|
||||
var _ StatusWriter = &typedClient{}
|
||||
|
||||
// client is a client.Client that reads and writes directly from/to an API server. It lazily initializes
|
||||
// new clients at the time they are used, and caches the client.
|
||||
@@ -42,6 +41,7 @@ func (c *typedClient) Create(ctx context.Context, obj Object, opts ...CreateOpti
|
||||
|
||||
createOpts := &CreateOptions{}
|
||||
createOpts.ApplyOptions(opts)
|
||||
|
||||
return o.Post().
|
||||
NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
|
||||
Resource(o.resource()).
|
||||
@@ -60,6 +60,7 @@ func (c *typedClient) Update(ctx context.Context, obj Object, opts ...UpdateOpti
|
||||
|
||||
updateOpts := &UpdateOptions{}
|
||||
updateOpts.ApplyOptions(opts)
|
||||
|
||||
return o.Put().
|
||||
NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
|
||||
Resource(o.resource()).
|
||||
@@ -121,25 +122,30 @@ func (c *typedClient) Patch(ctx context.Context, obj Object, patch Patch, opts .
|
||||
}
|
||||
|
||||
patchOpts := &PatchOptions{}
|
||||
patchOpts.ApplyOptions(opts)
|
||||
|
||||
return o.Patch(patch.Type()).
|
||||
NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
|
||||
Resource(o.resource()).
|
||||
Name(o.GetName()).
|
||||
VersionedParams(patchOpts.ApplyOptions(opts).AsPatchOptions(), c.paramCodec).
|
||||
VersionedParams(patchOpts.AsPatchOptions(), c.paramCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(obj)
|
||||
}
|
||||
|
||||
// Get implements client.Client.
|
||||
func (c *typedClient) Get(ctx context.Context, key ObjectKey, obj Object) error {
|
||||
func (c *typedClient) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error {
|
||||
r, err := c.cache.getResource(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
getOpts := GetOptions{}
|
||||
getOpts.ApplyOptions(opts)
|
||||
return r.Get().
|
||||
NamespaceIfScoped(key.Namespace, r.isNamespaced()).
|
||||
Resource(r.resource()).
|
||||
VersionedParams(getOpts.AsGetOptions(), c.paramCodec).
|
||||
Name(key.Name).Do(ctx).Into(obj)
|
||||
}
|
||||
|
||||
@@ -149,8 +155,10 @@ func (c *typedClient) List(ctx context.Context, obj ObjectList, opts ...ListOpti
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
listOpts := ListOptions{}
|
||||
listOpts.ApplyOptions(opts)
|
||||
|
||||
return r.Get().
|
||||
NamespaceIfScoped(listOpts.Namespace, r.isNamespaced()).
|
||||
Resource(r.resource()).
|
||||
@@ -159,8 +167,55 @@ func (c *typedClient) List(ctx context.Context, obj ObjectList, opts ...ListOpti
|
||||
Into(obj)
|
||||
}
|
||||
|
||||
// UpdateStatus used by StatusWriter to write status.
|
||||
func (c *typedClient) UpdateStatus(ctx context.Context, obj Object, opts ...UpdateOption) error {
|
||||
func (c *typedClient) GetSubResource(ctx context.Context, obj, subResourceObj Object, subResource string, opts ...SubResourceGetOption) error {
|
||||
o, err := c.cache.getObjMeta(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if subResourceObj.GetName() == "" {
|
||||
subResourceObj.SetName(obj.GetName())
|
||||
}
|
||||
|
||||
getOpts := &SubResourceGetOptions{}
|
||||
getOpts.ApplyOptions(opts)
|
||||
|
||||
return o.Get().
|
||||
NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
|
||||
Resource(o.resource()).
|
||||
Name(o.GetName()).
|
||||
SubResource(subResource).
|
||||
VersionedParams(getOpts.AsGetOptions(), c.paramCodec).
|
||||
Do(ctx).
|
||||
Into(subResourceObj)
|
||||
}
|
||||
|
||||
func (c *typedClient) CreateSubResource(ctx context.Context, obj Object, subResourceObj Object, subResource string, opts ...SubResourceCreateOption) error {
|
||||
o, err := c.cache.getObjMeta(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if subResourceObj.GetName() == "" {
|
||||
subResourceObj.SetName(obj.GetName())
|
||||
}
|
||||
|
||||
createOpts := &SubResourceCreateOptions{}
|
||||
createOpts.ApplyOptions(opts)
|
||||
|
||||
return o.Post().
|
||||
NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
|
||||
Resource(o.resource()).
|
||||
Name(o.GetName()).
|
||||
SubResource(subResource).
|
||||
Body(subResourceObj).
|
||||
VersionedParams(createOpts.AsCreateOptions(), c.paramCodec).
|
||||
Do(ctx).
|
||||
Into(subResourceObj)
|
||||
}
|
||||
|
||||
// UpdateSubResource used by SubResourceWriter to write status.
|
||||
func (c *typedClient) UpdateSubResource(ctx context.Context, obj Object, subResource string, opts ...SubResourceUpdateOption) error {
|
||||
o, err := c.cache.getObjMeta(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -169,37 +224,58 @@ func (c *typedClient) UpdateStatus(ctx context.Context, obj Object, opts ...Upda
|
||||
// wrapped to improve the UX ?
|
||||
// It will be nice to receive an error saying the object doesn't implement
|
||||
// status subresource and check CRD definition
|
||||
updateOpts := &SubResourceUpdateOptions{}
|
||||
updateOpts.ApplyOptions(opts)
|
||||
|
||||
body := obj
|
||||
if updateOpts.SubResourceBody != nil {
|
||||
body = updateOpts.SubResourceBody
|
||||
}
|
||||
if body.GetName() == "" {
|
||||
body.SetName(obj.GetName())
|
||||
}
|
||||
if body.GetNamespace() == "" {
|
||||
body.SetNamespace(obj.GetNamespace())
|
||||
}
|
||||
|
||||
return o.Put().
|
||||
NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
|
||||
Resource(o.resource()).
|
||||
Name(o.GetName()).
|
||||
SubResource("status").
|
||||
Body(obj).
|
||||
VersionedParams((&UpdateOptions{}).ApplyOptions(opts).AsUpdateOptions(), c.paramCodec).
|
||||
SubResource(subResource).
|
||||
Body(body).
|
||||
VersionedParams(updateOpts.AsUpdateOptions(), c.paramCodec).
|
||||
Do(ctx).
|
||||
Into(obj)
|
||||
Into(body)
|
||||
}
|
||||
|
||||
// PatchStatus used by StatusWriter to write status.
|
||||
func (c *typedClient) PatchStatus(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error {
|
||||
// PatchSubResource used by SubResourceWriter to write subresource.
|
||||
func (c *typedClient) PatchSubResource(ctx context.Context, obj Object, subResource string, patch Patch, opts ...SubResourcePatchOption) error {
|
||||
o, err := c.cache.getObjMeta(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := patch.Data(obj)
|
||||
patchOpts := &SubResourcePatchOptions{}
|
||||
patchOpts.ApplyOptions(opts)
|
||||
|
||||
body := obj
|
||||
if patchOpts.SubResourceBody != nil {
|
||||
body = patchOpts.SubResourceBody
|
||||
}
|
||||
|
||||
data, err := patch.Data(body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
patchOpts := &PatchOptions{}
|
||||
return o.Patch(patch.Type()).
|
||||
NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
|
||||
Resource(o.resource()).
|
||||
Name(o.GetName()).
|
||||
SubResource("status").
|
||||
SubResource(subResource).
|
||||
Body(data).
|
||||
VersionedParams(patchOpts.ApplyOptions(opts).AsPatchOptions(), c.paramCodec).
|
||||
VersionedParams(patchOpts.AsPatchOptions(), c.paramCodec).
|
||||
Do(ctx).
|
||||
Into(obj)
|
||||
Into(body)
|
||||
}
|
||||
|
||||
127
vendor/sigs.k8s.io/controller-runtime/pkg/client/unstructured_client.go
generated
vendored
127
vendor/sigs.k8s.io/controller-runtime/pkg/client/unstructured_client.go
generated
vendored
@@ -27,7 +27,6 @@ import (
|
||||
|
||||
var _ Reader = &unstructuredClient{}
|
||||
var _ Writer = &unstructuredClient{}
|
||||
var _ StatusWriter = &unstructuredClient{}
|
||||
|
||||
// client is a client.Client that reads and writes directly from/to an API server. It lazily initializes
|
||||
// new clients at the time they are used, and caches the client.
|
||||
@@ -52,6 +51,7 @@ func (uc *unstructuredClient) Create(ctx context.Context, obj Object, opts ...Cr
|
||||
|
||||
createOpts := &CreateOptions{}
|
||||
createOpts.ApplyOptions(opts)
|
||||
|
||||
result := o.Post().
|
||||
NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
|
||||
Resource(o.resource()).
|
||||
@@ -80,6 +80,7 @@ func (uc *unstructuredClient) Update(ctx context.Context, obj Object, opts ...Up
|
||||
|
||||
updateOpts := UpdateOptions{}
|
||||
updateOpts.ApplyOptions(opts)
|
||||
|
||||
result := o.Put().
|
||||
NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
|
||||
Resource(o.resource()).
|
||||
@@ -106,6 +107,7 @@ func (uc *unstructuredClient) Delete(ctx context.Context, obj Object, opts ...De
|
||||
|
||||
deleteOpts := DeleteOptions{}
|
||||
deleteOpts.ApplyOptions(opts)
|
||||
|
||||
return o.Delete().
|
||||
NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
|
||||
Resource(o.resource()).
|
||||
@@ -128,6 +130,7 @@ func (uc *unstructuredClient) DeleteAllOf(ctx context.Context, obj Object, opts
|
||||
|
||||
deleteAllOfOpts := DeleteAllOfOptions{}
|
||||
deleteAllOfOpts.ApplyOptions(opts)
|
||||
|
||||
return o.Delete().
|
||||
NamespaceIfScoped(deleteAllOfOpts.ListOptions.Namespace, o.isNamespaced()).
|
||||
Resource(o.resource()).
|
||||
@@ -154,18 +157,20 @@ func (uc *unstructuredClient) Patch(ctx context.Context, obj Object, patch Patch
|
||||
}
|
||||
|
||||
patchOpts := &PatchOptions{}
|
||||
patchOpts.ApplyOptions(opts)
|
||||
|
||||
return o.Patch(patch.Type()).
|
||||
NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
|
||||
Resource(o.resource()).
|
||||
Name(o.GetName()).
|
||||
VersionedParams(patchOpts.ApplyOptions(opts).AsPatchOptions(), uc.paramCodec).
|
||||
VersionedParams(patchOpts.AsPatchOptions(), uc.paramCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(obj)
|
||||
}
|
||||
|
||||
// Get implements client.Client.
|
||||
func (uc *unstructuredClient) Get(ctx context.Context, key ObjectKey, obj Object) error {
|
||||
func (uc *unstructuredClient) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error {
|
||||
u, ok := obj.(*unstructured.Unstructured)
|
||||
if !ok {
|
||||
return fmt.Errorf("unstructured client did not understand object: %T", obj)
|
||||
@@ -173,6 +178,9 @@ func (uc *unstructuredClient) Get(ctx context.Context, key ObjectKey, obj Object
|
||||
|
||||
gvk := u.GroupVersionKind()
|
||||
|
||||
getOpts := GetOptions{}
|
||||
getOpts.ApplyOptions(opts)
|
||||
|
||||
r, err := uc.cache.getResource(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -181,6 +189,7 @@ func (uc *unstructuredClient) Get(ctx context.Context, key ObjectKey, obj Object
|
||||
result := r.Get().
|
||||
NamespaceIfScoped(key.Namespace, r.isNamespaced()).
|
||||
Resource(r.resource()).
|
||||
VersionedParams(getOpts.AsGetOptions(), uc.paramCodec).
|
||||
Name(key.Name).
|
||||
Do(ctx).
|
||||
Into(obj)
|
||||
@@ -200,14 +209,14 @@ func (uc *unstructuredClient) List(ctx context.Context, obj ObjectList, opts ...
|
||||
gvk := u.GroupVersionKind()
|
||||
gvk.Kind = strings.TrimSuffix(gvk.Kind, "List")
|
||||
|
||||
listOpts := ListOptions{}
|
||||
listOpts.ApplyOptions(opts)
|
||||
|
||||
r, err := uc.cache.getResource(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
listOpts := ListOptions{}
|
||||
listOpts.ApplyOptions(opts)
|
||||
|
||||
return r.Get().
|
||||
NamespaceIfScoped(listOpts.Namespace, r.isNamespaced()).
|
||||
Resource(r.resource()).
|
||||
@@ -216,7 +225,70 @@ func (uc *unstructuredClient) List(ctx context.Context, obj ObjectList, opts ...
|
||||
Into(obj)
|
||||
}
|
||||
|
||||
func (uc *unstructuredClient) UpdateStatus(ctx context.Context, obj Object, opts ...UpdateOption) error {
|
||||
func (uc *unstructuredClient) GetSubResource(ctx context.Context, obj, subResourceObj Object, subResource string, opts ...SubResourceGetOption) error {
|
||||
if _, ok := obj.(*unstructured.Unstructured); !ok {
|
||||
return fmt.Errorf("unstructured client did not understand object: %T", subResource)
|
||||
}
|
||||
|
||||
if _, ok := subResourceObj.(*unstructured.Unstructured); !ok {
|
||||
return fmt.Errorf("unstructured client did not understand object: %T", obj)
|
||||
}
|
||||
|
||||
if subResourceObj.GetName() == "" {
|
||||
subResourceObj.SetName(obj.GetName())
|
||||
}
|
||||
|
||||
o, err := uc.cache.getObjMeta(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
getOpts := &SubResourceGetOptions{}
|
||||
getOpts.ApplyOptions(opts)
|
||||
|
||||
return o.Get().
|
||||
NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
|
||||
Resource(o.resource()).
|
||||
Name(o.GetName()).
|
||||
SubResource(subResource).
|
||||
VersionedParams(getOpts.AsGetOptions(), uc.paramCodec).
|
||||
Do(ctx).
|
||||
Into(subResourceObj)
|
||||
}
|
||||
|
||||
func (uc *unstructuredClient) CreateSubResource(ctx context.Context, obj, subResourceObj Object, subResource string, opts ...SubResourceCreateOption) error {
|
||||
if _, ok := obj.(*unstructured.Unstructured); !ok {
|
||||
return fmt.Errorf("unstructured client did not understand object: %T", subResourceObj)
|
||||
}
|
||||
|
||||
if _, ok := subResourceObj.(*unstructured.Unstructured); !ok {
|
||||
return fmt.Errorf("unstructured client did not understand object: %T", obj)
|
||||
}
|
||||
|
||||
if subResourceObj.GetName() == "" {
|
||||
subResourceObj.SetName(obj.GetName())
|
||||
}
|
||||
|
||||
o, err := uc.cache.getObjMeta(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
createOpts := &SubResourceCreateOptions{}
|
||||
createOpts.ApplyOptions(opts)
|
||||
|
||||
return o.Post().
|
||||
NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
|
||||
Resource(o.resource()).
|
||||
Name(o.GetName()).
|
||||
SubResource(subResource).
|
||||
Body(subResourceObj).
|
||||
VersionedParams(createOpts.AsCreateOptions(), uc.paramCodec).
|
||||
Do(ctx).
|
||||
Into(subResourceObj)
|
||||
}
|
||||
|
||||
func (uc *unstructuredClient) UpdateSubResource(ctx context.Context, obj Object, subResource string, opts ...SubResourceUpdateOption) error {
|
||||
if _, ok := obj.(*unstructured.Unstructured); !ok {
|
||||
return fmt.Errorf("unstructured client did not understand object: %T", obj)
|
||||
}
|
||||
@@ -226,18 +298,32 @@ func (uc *unstructuredClient) UpdateStatus(ctx context.Context, obj Object, opts
|
||||
return err
|
||||
}
|
||||
|
||||
updateOpts := SubResourceUpdateOptions{}
|
||||
updateOpts.ApplyOptions(opts)
|
||||
|
||||
body := obj
|
||||
if updateOpts.SubResourceBody != nil {
|
||||
body = updateOpts.SubResourceBody
|
||||
}
|
||||
if body.GetName() == "" {
|
||||
body.SetName(obj.GetName())
|
||||
}
|
||||
if body.GetNamespace() == "" {
|
||||
body.SetNamespace(obj.GetNamespace())
|
||||
}
|
||||
|
||||
return o.Put().
|
||||
NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
|
||||
Resource(o.resource()).
|
||||
Name(o.GetName()).
|
||||
SubResource("status").
|
||||
Body(obj).
|
||||
VersionedParams((&UpdateOptions{}).ApplyOptions(opts).AsUpdateOptions(), uc.paramCodec).
|
||||
SubResource(subResource).
|
||||
Body(body).
|
||||
VersionedParams(updateOpts.AsUpdateOptions(), uc.paramCodec).
|
||||
Do(ctx).
|
||||
Into(obj)
|
||||
Into(body)
|
||||
}
|
||||
|
||||
func (uc *unstructuredClient) PatchStatus(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error {
|
||||
func (uc *unstructuredClient) PatchSubResource(ctx context.Context, obj Object, subResource string, patch Patch, opts ...SubResourcePatchOption) error {
|
||||
u, ok := obj.(*unstructured.Unstructured)
|
||||
if !ok {
|
||||
return fmt.Errorf("unstructured client did not understand object: %T", obj)
|
||||
@@ -250,21 +336,28 @@ func (uc *unstructuredClient) PatchStatus(ctx context.Context, obj Object, patch
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := patch.Data(obj)
|
||||
patchOpts := &SubResourcePatchOptions{}
|
||||
patchOpts.ApplyOptions(opts)
|
||||
|
||||
body := obj
|
||||
if patchOpts.SubResourceBody != nil {
|
||||
body = patchOpts.SubResourceBody
|
||||
}
|
||||
|
||||
data, err := patch.Data(body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
patchOpts := &PatchOptions{}
|
||||
result := o.Patch(patch.Type()).
|
||||
NamespaceIfScoped(o.GetNamespace(), o.isNamespaced()).
|
||||
Resource(o.resource()).
|
||||
Name(o.GetName()).
|
||||
SubResource("status").
|
||||
SubResource(subResource).
|
||||
Body(data).
|
||||
VersionedParams(patchOpts.ApplyOptions(opts).AsPatchOptions(), uc.paramCodec).
|
||||
VersionedParams(patchOpts.AsPatchOptions(), uc.paramCodec).
|
||||
Do(ctx).
|
||||
Into(u)
|
||||
Into(body)
|
||||
|
||||
u.SetGroupVersionKind(gvk)
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user