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:
3
vendor/sigs.k8s.io/controller-runtime/.gitignore
generated
vendored
3
vendor/sigs.k8s.io/controller-runtime/.gitignore
generated
vendored
@@ -22,3 +22,6 @@
|
||||
|
||||
# Tools binaries.
|
||||
hack/tools/bin
|
||||
|
||||
junit-report.xml
|
||||
/artifacts
|
||||
15
vendor/sigs.k8s.io/controller-runtime/.golangci.yml
generated
vendored
15
vendor/sigs.k8s.io/controller-runtime/.golangci.yml
generated
vendored
@@ -3,7 +3,6 @@ linters:
|
||||
enable:
|
||||
- asciicheck
|
||||
- bodyclose
|
||||
- deadcode
|
||||
- depguard
|
||||
- dogsled
|
||||
- errcheck
|
||||
@@ -12,14 +11,12 @@ linters:
|
||||
- goconst
|
||||
- gocritic
|
||||
- gocyclo
|
||||
- godot
|
||||
- gofmt
|
||||
- goimports
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
- gosimple
|
||||
- govet
|
||||
- ifshort
|
||||
- importas
|
||||
- ineffassign
|
||||
- misspell
|
||||
@@ -30,19 +27,14 @@ linters:
|
||||
- revive
|
||||
- rowserrcheck
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- stylecheck
|
||||
- typecheck
|
||||
- unconvert
|
||||
- unparam
|
||||
- unused
|
||||
- varcheck
|
||||
- whitespace
|
||||
|
||||
linters-settings:
|
||||
ifshort:
|
||||
# Maximum length of variable declaration measured in number of characters, after which linter won't suggest using short syntax.
|
||||
max-decl-chars: 50
|
||||
importas:
|
||||
no-unaliased: true
|
||||
alias:
|
||||
@@ -61,9 +53,9 @@ linters-settings:
|
||||
- pkg: sigs.k8s.io/controller-runtime
|
||||
alias: ctrl
|
||||
staticcheck:
|
||||
go: "1.18"
|
||||
go: "1.19"
|
||||
stylecheck:
|
||||
go: "1.18"
|
||||
go: "1.19"
|
||||
depguard:
|
||||
include-go-root: true
|
||||
packages:
|
||||
@@ -132,6 +124,9 @@ issues:
|
||||
- linters:
|
||||
- gosec
|
||||
text: "G304: Potential file inclusion via variable"
|
||||
- linters:
|
||||
- revive
|
||||
text: "package-comments: should have a package comment"
|
||||
|
||||
run:
|
||||
timeout: 10m
|
||||
|
||||
16
vendor/sigs.k8s.io/controller-runtime/OWNERS_ALIASES
generated
vendored
16
vendor/sigs.k8s.io/controller-runtime/OWNERS_ALIASES
generated
vendored
@@ -4,9 +4,8 @@ aliases:
|
||||
# active folks who can be contacted to perform admin-related
|
||||
# tasks on the repo, or otherwise approve any PRS.
|
||||
controller-runtime-admins:
|
||||
- droot
|
||||
- mengqiy
|
||||
- pwittrock
|
||||
- vincepri
|
||||
- joelanford
|
||||
|
||||
# non-admin folks who have write-access and can approve any PRs in the repo
|
||||
controller-runtime-maintainers:
|
||||
@@ -15,19 +14,18 @@ aliases:
|
||||
|
||||
# non-admin folks who can approve any PRs in the repo
|
||||
controller-runtime-approvers:
|
||||
- gerred
|
||||
- shawn-hurley
|
||||
- alvaroaleman
|
||||
- fillzpp
|
||||
- sbueringer
|
||||
|
||||
# folks who can review and LGTM any PRs in the repo (doesn't
|
||||
# include approvers & admins -- those count too via the OWNERS
|
||||
# file)
|
||||
controller-runtime-reviewers:
|
||||
- alenkacz
|
||||
- vincepri
|
||||
- alexeldeib
|
||||
- varshaprasad96
|
||||
- fillzpp
|
||||
- sbueringer
|
||||
|
||||
# folks to can approve things in the directly-ported
|
||||
# testing_frameworks portions of the codebase
|
||||
@@ -39,3 +37,7 @@ aliases:
|
||||
# but are no longer directly involved
|
||||
controller-runtime-emeritus-maintainers:
|
||||
- directxman12
|
||||
controller-runtime-emeritus-admins:
|
||||
- droot
|
||||
- mengqiy
|
||||
- pwittrock
|
||||
|
||||
2
vendor/sigs.k8s.io/controller-runtime/README.md
generated
vendored
2
vendor/sigs.k8s.io/controller-runtime/README.md
generated
vendored
@@ -53,7 +53,7 @@ in sig apimachinery.
|
||||
|
||||
You can reach the maintainers of this project at:
|
||||
|
||||
- Slack channel: [#kubebuilder](http://slack.k8s.io/#kubebuilder)
|
||||
- Slack channel: [#controller-runtime](https://kubernetes.slack.com/archives/C02MRBMN00Z)
|
||||
- Google Group: [kubebuilder@googlegroups.com](https://groups.google.com/forum/#!forum/kubebuilder)
|
||||
|
||||
## Contributing
|
||||
|
||||
47
vendor/sigs.k8s.io/controller-runtime/RELEASE.md
generated
vendored
Normal file
47
vendor/sigs.k8s.io/controller-runtime/RELEASE.md
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
# Release Process
|
||||
|
||||
The Kubernetes controller-runtime Project is released on an as-needed basis. The process is as follows:
|
||||
|
||||
**Note:** Releases are done from the `release-MAJOR.MINOR` branches. For PATCH releases is not required
|
||||
to create a new branch you will just need to ensure that all big fixes are cherry-picked into the respective
|
||||
`release-MAJOR.MINOR` branch. To know more about versioning check https://semver.org/.
|
||||
|
||||
## How to do a release
|
||||
|
||||
### Create the new branch and the release tag
|
||||
|
||||
1. Create a new branch `git checkout -b release-<MAJOR.MINOR>` from master
|
||||
2. Push the new branch to the remote repository
|
||||
|
||||
### Now, let's generate the changelog
|
||||
|
||||
1. Create the changelog from the new branch `release-<MAJOR.MINOR>` (`git checkout release-<MAJOR.MINOR>`).
|
||||
You will need to use the [kubebuilder-release-tools][kubebuilder-release-tools] to generate the notes. See [here][release-notes-generation]
|
||||
|
||||
> **Note**
|
||||
> - You will need to have checkout locally from the remote repository the previous branch
|
||||
> - Also, ensure that you fetch all tags from the remote `git fetch --all --tags`
|
||||
|
||||
### Draft a new release from GitHub
|
||||
|
||||
1. Create a new tag with the correct version from the new `release-<MAJOR.MINOR>` branch
|
||||
2. Add the changelog on it and publish. Now, the code source is released !
|
||||
|
||||
### Add a new Prow test the for the new branch release
|
||||
|
||||
1. Create a new prow test under [github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/controller-runtime](https://github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/controller-runtime)
|
||||
for the new `release-<MAJOR.MINOR>` branch. (i.e. for the `0.11.0` release see the PR: https://github.com/kubernetes/test-infra/pull/25205)
|
||||
2. Ping the infra PR in the controller-runtime slack channel for reviews.
|
||||
|
||||
### Announce the new release:
|
||||
|
||||
1. Publish on the Slack channel the new release, i.e:
|
||||
|
||||
````
|
||||
:announce: Controller-Runtime v0.12.0 has been released!
|
||||
This release includes a Kubernetes dependency bump to v1.24.
|
||||
For more info, see the release page: https://github.com/kubernetes-sigs/controller-runtime/releases.
|
||||
:tada: Thanks to all our contributors!
|
||||
````
|
||||
|
||||
2. An announcement email is sent to `kubebuilder@googlegroups.com` with the subject `[ANNOUNCE] Controller-Runtime $VERSION is released`
|
||||
4
vendor/sigs.k8s.io/controller-runtime/TMP-LOGGING.md
generated
vendored
4
vendor/sigs.k8s.io/controller-runtime/TMP-LOGGING.md
generated
vendored
@@ -21,7 +21,7 @@ log.Printf("starting reconciliation for pod %s/%s", podNamespace, podName)
|
||||
In controller-runtime, we'd instead write:
|
||||
|
||||
```go
|
||||
logger.Info("starting reconciliation", "pod", req.NamespacedNamed)
|
||||
logger.Info("starting reconciliation", "pod", req.NamespacedName)
|
||||
```
|
||||
|
||||
or even write
|
||||
@@ -51,7 +51,7 @@ You can configure the logging implementation using
|
||||
`"sigs.k8s.io/controller-runtime/pkg/log".SetLogger`. That
|
||||
package also contains the convenience functions for setting up Zap.
|
||||
|
||||
You can get a handle to the the "root" logger using
|
||||
You can get a handle to the "root" logger using
|
||||
`"sigs.k8s.io/controller-runtime/pkg/log".Log`, and can then call
|
||||
`WithName` to create individual named loggers. You can call `WithName`
|
||||
repeatedly to chain names together:
|
||||
|
||||
9
vendor/sigs.k8s.io/controller-runtime/alias.go
generated
vendored
9
vendor/sigs.k8s.io/controller-runtime/alias.go
generated
vendored
@@ -21,7 +21,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/builder"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/config"
|
||||
cfg "sigs.k8s.io/controller-runtime/pkg/config"
|
||||
cfg "sigs.k8s.io/controller-runtime/pkg/config" //nolint:staticcheck
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/manager"
|
||||
@@ -70,6 +70,10 @@ type TypeMeta = metav1.TypeMeta
|
||||
type ObjectMeta = metav1.ObjectMeta
|
||||
|
||||
var (
|
||||
// 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.
|
||||
RegisterFlags = config.RegisterFlags
|
||||
|
||||
// GetConfigOrDie creates a *rest.Config for talking to a Kubernetes apiserver.
|
||||
// If --kubeconfig is set, will use the kubeconfig file at that location. Otherwise will assume running
|
||||
// in cluster and use the cluster provided kubeconfig.
|
||||
@@ -95,7 +99,8 @@ var (
|
||||
// ConfigFile returns the cfg.File function for deferred config file loading,
|
||||
// this is passed into Options{}.From() to populate the Options fields for
|
||||
// the manager.
|
||||
ConfigFile = cfg.File
|
||||
// Deprecated: This is deprecated in favor of using Options directly.
|
||||
ConfigFile = cfg.File //nolint:staticcheck
|
||||
|
||||
// NewControllerManagedBy returns a new controller builder that will be started by the provided Manager.
|
||||
NewControllerManagedBy = builder.ControllerManagedBy
|
||||
|
||||
27
vendor/sigs.k8s.io/controller-runtime/doc.go
generated
vendored
27
vendor/sigs.k8s.io/controller-runtime/doc.go
generated
vendored
@@ -23,13 +23,14 @@ limitations under the License.
|
||||
// and uncommon cases should be possible. In general, controller-runtime tries
|
||||
// to guide users towards Kubernetes controller best-practices.
|
||||
//
|
||||
// Getting Started
|
||||
// # Getting Started
|
||||
//
|
||||
// The main entrypoint for controller-runtime is this root package, which
|
||||
// contains all of the common types needed to get started building controllers:
|
||||
// import (
|
||||
// ctrl "sigs.k8s.io/controller-runtime"
|
||||
// )
|
||||
//
|
||||
// import (
|
||||
// ctrl "sigs.k8s.io/controller-runtime"
|
||||
// )
|
||||
//
|
||||
// The examples in this package walk through a basic controller setup. The
|
||||
// kubebuilder book (https://book.kubebuilder.io) has some more in-depth
|
||||
@@ -38,7 +39,7 @@ limitations under the License.
|
||||
// controller-runtime favors structs with sane defaults over constructors, so
|
||||
// it's fairly common to see structs being used directly in controller-runtime.
|
||||
//
|
||||
// Organization
|
||||
// # Organization
|
||||
//
|
||||
// A brief-ish walkthrough of the layout of this library can be found below. Each
|
||||
// package contains more information about how to use it.
|
||||
@@ -47,7 +48,7 @@ limitations under the License.
|
||||
// controllers can be found at
|
||||
// https://github.com/kubernetes-sigs/controller-runtime/blob/master/FAQ.md.
|
||||
//
|
||||
// Managers
|
||||
// # Managers
|
||||
//
|
||||
// Every controller and webhook is ultimately run by a Manager (pkg/manager). A
|
||||
// manager is responsible for running controllers and webhooks, and setting up
|
||||
@@ -56,7 +57,7 @@ limitations under the License.
|
||||
// generally configured to gracefully shut down controllers on pod termination
|
||||
// by wiring up a signal handler (pkg/manager/signals).
|
||||
//
|
||||
// Controllers
|
||||
// # Controllers
|
||||
//
|
||||
// Controllers (pkg/controller) use events (pkg/event) to eventually trigger
|
||||
// reconcile requests. They may be constructed manually, but are often
|
||||
@@ -67,7 +68,7 @@ limitations under the License.
|
||||
// trigger reconciles. There are pre-written utilities for the common cases, and
|
||||
// interfaces and helpers for advanced cases.
|
||||
//
|
||||
// Reconcilers
|
||||
// # Reconcilers
|
||||
//
|
||||
// Controller logic is implemented in terms of Reconcilers (pkg/reconcile). A
|
||||
// Reconciler implements a function which takes a reconcile Request containing
|
||||
@@ -75,7 +76,7 @@ limitations under the License.
|
||||
// and returns a Response or an error indicating whether to requeue for a
|
||||
// second round of processing.
|
||||
//
|
||||
// Clients and Caches
|
||||
// # Clients and Caches
|
||||
//
|
||||
// Reconcilers use Clients (pkg/client) to access API objects. The default
|
||||
// client provided by the manager reads from a local shared cache (pkg/cache)
|
||||
@@ -91,19 +92,19 @@ limitations under the License.
|
||||
// may retrieve event recorders (pkg/recorder) to emit events using the
|
||||
// manager.
|
||||
//
|
||||
// Schemes
|
||||
// # Schemes
|
||||
//
|
||||
// Clients, Caches, and many other things in Kubernetes use Schemes
|
||||
// (pkg/scheme) to associate Go types to Kubernetes API Kinds
|
||||
// (Group-Version-Kinds, to be specific).
|
||||
//
|
||||
// Webhooks
|
||||
// # Webhooks
|
||||
//
|
||||
// Similarly, webhooks (pkg/webhook/admission) may be implemented directly, but
|
||||
// are often constructed using a builder (pkg/webhook/admission/builder). They
|
||||
// are run via a server (pkg/webhook) which is managed by a Manager.
|
||||
//
|
||||
// Logging and Metrics
|
||||
// # Logging and Metrics
|
||||
//
|
||||
// Logging (pkg/log) in controller-runtime is done via structured logs, using a
|
||||
// log set of interfaces called logr
|
||||
@@ -117,7 +118,7 @@ limitations under the License.
|
||||
// serve these by an HTTP endpoint, and additional metrics may be registered to
|
||||
// this Registry as normal.
|
||||
//
|
||||
// Testing
|
||||
// # Testing
|
||||
//
|
||||
// You can easily build integration and unit tests for your controllers and
|
||||
// webhooks using the test Environment (pkg/envtest). This will automatically
|
||||
|
||||
76
vendor/sigs.k8s.io/controller-runtime/pkg/builder/controller.go
generated
vendored
76
vendor/sigs.k8s.io/controller-runtime/pkg/builder/controller.go
generated
vendored
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package builder
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
@@ -182,10 +183,6 @@ func (blder *Builder) Build(r reconcile.Reconciler) (controller.Controller, erro
|
||||
if blder.forInput.err != nil {
|
||||
return nil, blder.forInput.err
|
||||
}
|
||||
// Checking the reconcile type exist or not
|
||||
if blder.forInput.object == nil {
|
||||
return nil, fmt.Errorf("must provide an object for reconciliation")
|
||||
}
|
||||
|
||||
// Set the ControllerManagedBy
|
||||
if err := blder.doController(r); err != nil {
|
||||
@@ -219,18 +216,23 @@ func (blder *Builder) project(obj client.Object, proj objectProjection) (client.
|
||||
|
||||
func (blder *Builder) doWatch() error {
|
||||
// Reconcile type
|
||||
typeForSrc, err := blder.project(blder.forInput.object, blder.forInput.objectProjection)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
src := &source.Kind{Type: typeForSrc}
|
||||
hdler := &handler.EnqueueRequestForObject{}
|
||||
allPredicates := append(blder.globalPredicates, blder.forInput.predicates...)
|
||||
if err := blder.ctrl.Watch(src, hdler, allPredicates...); err != nil {
|
||||
return err
|
||||
if blder.forInput.object != nil {
|
||||
typeForSrc, err := blder.project(blder.forInput.object, blder.forInput.objectProjection)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
src := &source.Kind{Type: typeForSrc}
|
||||
hdler := &handler.EnqueueRequestForObject{}
|
||||
allPredicates := append(blder.globalPredicates, blder.forInput.predicates...)
|
||||
if err := blder.ctrl.Watch(src, hdler, allPredicates...); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Watches the managed types
|
||||
if len(blder.ownsInput) > 0 && blder.forInput.object == nil {
|
||||
return errors.New("Owns() can only be used together with For()")
|
||||
}
|
||||
for _, own := range blder.ownsInput {
|
||||
typeForSrc, err := blder.project(own.object, own.objectProjection)
|
||||
if err != nil {
|
||||
@@ -249,6 +251,9 @@ func (blder *Builder) doWatch() error {
|
||||
}
|
||||
|
||||
// Do the watch requests
|
||||
if len(blder.watchesInput) == 0 && blder.forInput.object == nil {
|
||||
return errors.New("there are no watches configured, controller will never get triggered. Use For(), Owns() or Watches() to set them up")
|
||||
}
|
||||
for _, w := range blder.watchesInput {
|
||||
allPredicates := append([]predicate.Predicate(nil), blder.globalPredicates...)
|
||||
allPredicates = append(allPredicates, w.predicates...)
|
||||
@@ -269,15 +274,18 @@ func (blder *Builder) doWatch() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (blder *Builder) getControllerName(gvk schema.GroupVersionKind) string {
|
||||
func (blder *Builder) getControllerName(gvk schema.GroupVersionKind, hasGVK bool) (string, error) {
|
||||
if blder.name != "" {
|
||||
return blder.name
|
||||
return blder.name, nil
|
||||
}
|
||||
return strings.ToLower(gvk.Kind)
|
||||
if !hasGVK {
|
||||
return "", errors.New("one of For() or Named() must be called")
|
||||
}
|
||||
return strings.ToLower(gvk.Kind), nil
|
||||
}
|
||||
|
||||
func (blder *Builder) doController(r reconcile.Reconciler) error {
|
||||
globalOpts := blder.mgr.GetControllerOptions()
|
||||
globalOpts := blder.mgr.GetControllerOptions() //nolint:staticcheck
|
||||
|
||||
ctrlOptions := blder.ctrlOptions
|
||||
if ctrlOptions.Reconciler == nil {
|
||||
@@ -286,13 +294,18 @@ func (blder *Builder) doController(r reconcile.Reconciler) error {
|
||||
|
||||
// Retrieve the GVK from the object we're reconciling
|
||||
// to prepopulate logger information, and to optionally generate a default name.
|
||||
gvk, err := getGvk(blder.forInput.object, blder.mgr.GetScheme())
|
||||
if err != nil {
|
||||
return err
|
||||
var gvk schema.GroupVersionKind
|
||||
hasGVK := blder.forInput.object != nil
|
||||
if hasGVK {
|
||||
var err error
|
||||
gvk, err = getGvk(blder.forInput.object, blder.mgr.GetScheme())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Setup concurrency.
|
||||
if ctrlOptions.MaxConcurrentReconciles == 0 {
|
||||
if ctrlOptions.MaxConcurrentReconciles == 0 && hasGVK {
|
||||
groupKind := gvk.GroupKind().String()
|
||||
|
||||
if concurrency, ok := globalOpts.GroupKindConcurrency[groupKind]; ok && concurrency > 0 {
|
||||
@@ -305,23 +318,30 @@ func (blder *Builder) doController(r reconcile.Reconciler) error {
|
||||
ctrlOptions.CacheSyncTimeout = *globalOpts.CacheSyncTimeout
|
||||
}
|
||||
|
||||
controllerName := blder.getControllerName(gvk)
|
||||
controllerName, err := blder.getControllerName(gvk, hasGVK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Setup the logger.
|
||||
if ctrlOptions.LogConstructor == nil {
|
||||
log = blder.mgr.GetLogger().WithValues(
|
||||
log := blder.mgr.GetLogger().WithValues(
|
||||
"controller", controllerName,
|
||||
"controllerGroup", gvk.Group,
|
||||
"controllerKind", gvk.Kind,
|
||||
)
|
||||
|
||||
lowerCamelCaseKind := strings.ToLower(gvk.Kind[:1]) + gvk.Kind[1:]
|
||||
if hasGVK {
|
||||
log = log.WithValues(
|
||||
"controllerGroup", gvk.Group,
|
||||
"controllerKind", gvk.Kind,
|
||||
)
|
||||
}
|
||||
|
||||
ctrlOptions.LogConstructor = func(req *reconcile.Request) logr.Logger {
|
||||
log := log
|
||||
if req != nil {
|
||||
if hasGVK {
|
||||
log = log.WithValues(gvk.Kind, klog.KRef(req.Namespace, req.Name))
|
||||
}
|
||||
log = log.WithValues(
|
||||
lowerCamelCaseKind, klog.KRef(req.Namespace, req.Name),
|
||||
"namespace", req.Namespace, "name", req.Name,
|
||||
)
|
||||
}
|
||||
|
||||
4
vendor/sigs.k8s.io/controller-runtime/pkg/builder/options.go
generated
vendored
4
vendor/sigs.k8s.io/controller-runtime/pkg/builder/options.go
generated
vendored
@@ -101,9 +101,9 @@ func (p projectAs) ApplyToWatches(opts *WatchesInput) {
|
||||
|
||||
var (
|
||||
// OnlyMetadata tells the controller to *only* cache metadata, and to watch
|
||||
// the the API server in metadata-only form. This is useful when watching
|
||||
// the API server in metadata-only form. This is useful when watching
|
||||
// lots of objects, really big objects, or objects for which you only know
|
||||
// the the GVK, but not the structure. You'll need to pass
|
||||
// the GVK, but not the structure. You'll need to pass
|
||||
// metav1.PartialObjectMetadata to the client when fetching objects in your
|
||||
// reconciler, otherwise you'll end up with a duplicate structured or
|
||||
// unstructured cache.
|
||||
|
||||
15
vendor/sigs.k8s.io/controller-runtime/pkg/builder/webhook.go
generated
vendored
15
vendor/sigs.k8s.io/controller-runtime/pkg/builder/webhook.go
generated
vendored
@@ -39,6 +39,7 @@ type WebhookBuilder struct {
|
||||
gvk schema.GroupVersionKind
|
||||
mgr manager.Manager
|
||||
config *rest.Config
|
||||
recoverPanic bool
|
||||
}
|
||||
|
||||
// WebhookManagedBy allows inform its manager.Manager.
|
||||
@@ -68,6 +69,12 @@ func (blder *WebhookBuilder) WithValidator(validator admission.CustomValidator)
|
||||
return blder
|
||||
}
|
||||
|
||||
// RecoverPanic indicates whether the panic caused by webhook should be recovered.
|
||||
func (blder *WebhookBuilder) RecoverPanic() *WebhookBuilder {
|
||||
blder.recoverPanic = true
|
||||
return blder
|
||||
}
|
||||
|
||||
// Complete builds the webhook.
|
||||
func (blder *WebhookBuilder) Complete() error {
|
||||
// Set the Config
|
||||
@@ -124,10 +131,10 @@ func (blder *WebhookBuilder) registerDefaultingWebhook() {
|
||||
|
||||
func (blder *WebhookBuilder) getDefaultingWebhook() *admission.Webhook {
|
||||
if defaulter := blder.withDefaulter; defaulter != nil {
|
||||
return admission.WithCustomDefaulter(blder.apiType, defaulter)
|
||||
return admission.WithCustomDefaulter(blder.apiType, defaulter).WithRecoverPanic(blder.recoverPanic)
|
||||
}
|
||||
if defaulter, ok := blder.apiType.(admission.Defaulter); ok {
|
||||
return admission.DefaultingWebhookFor(defaulter)
|
||||
return admission.DefaultingWebhookFor(defaulter).WithRecoverPanic(blder.recoverPanic)
|
||||
}
|
||||
log.Info(
|
||||
"skip registering a mutating webhook, object does not implement admission.Defaulter or WithDefaulter wasn't called",
|
||||
@@ -153,10 +160,10 @@ func (blder *WebhookBuilder) registerValidatingWebhook() {
|
||||
|
||||
func (blder *WebhookBuilder) getValidatingWebhook() *admission.Webhook {
|
||||
if validator := blder.withValidator; validator != nil {
|
||||
return admission.WithCustomValidator(blder.apiType, validator)
|
||||
return admission.WithCustomValidator(blder.apiType, validator).WithRecoverPanic(blder.recoverPanic)
|
||||
}
|
||||
if validator, ok := blder.apiType.(admission.Validator); ok {
|
||||
return admission.ValidatingWebhookFor(validator)
|
||||
return admission.ValidatingWebhookFor(validator).WithRecoverPanic(blder.recoverPanic)
|
||||
}
|
||||
log.Info(
|
||||
"skip registering a validating webhook, object does not implement admission.Validator or WithValidator wasn't called",
|
||||
|
||||
337
vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go
generated
vendored
337
vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go
generated
vendored
@@ -19,14 +19,18 @@ package cache
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/rest"
|
||||
toolscache "k8s.io/client-go/tools/cache"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/cache/internal"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||
@@ -74,11 +78,19 @@ type Informer interface {
|
||||
// AddEventHandler adds an event handler to the shared informer using the shared informer's resync
|
||||
// period. Events to a single handler are delivered sequentially, but there is no coordination
|
||||
// between different handlers.
|
||||
AddEventHandler(handler toolscache.ResourceEventHandler)
|
||||
// It returns a registration handle for the handler that can be used to remove
|
||||
// the handler again.
|
||||
AddEventHandler(handler toolscache.ResourceEventHandler) (toolscache.ResourceEventHandlerRegistration, error)
|
||||
// AddEventHandlerWithResyncPeriod adds an event handler to the shared informer using the
|
||||
// specified resync period. Events to a single handler are delivered sequentially, but there is
|
||||
// no coordination between different handlers.
|
||||
AddEventHandlerWithResyncPeriod(handler toolscache.ResourceEventHandler, resyncPeriod time.Duration)
|
||||
// It returns a registration handle for the handler that can be used to remove
|
||||
// the handler again and an error if the handler cannot be added.
|
||||
AddEventHandlerWithResyncPeriod(handler toolscache.ResourceEventHandler, resyncPeriod time.Duration) (toolscache.ResourceEventHandlerRegistration, error)
|
||||
// RemoveEventHandler removes a formerly added event handler given by
|
||||
// its registration handle.
|
||||
// This function is guaranteed to be idempotent, and thread-safe.
|
||||
RemoveEventHandler(handle toolscache.ResourceEventHandlerRegistration) error
|
||||
// AddIndexers adds more indexers to this store. If you call this after you already have data
|
||||
// in the store, the results are undefined.
|
||||
AddIndexers(indexers toolscache.Indexers) error
|
||||
@@ -150,7 +162,7 @@ func New(config *rest.Config, opts Options) (Cache, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selectorsByGVK, err := convertToSelectorsByGVK(opts.SelectorsByObject, opts.DefaultSelector, opts.Scheme)
|
||||
selectorsByGVK, err := convertToByGVK(opts.SelectorsByObject, opts.DefaultSelector, opts.Scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -158,41 +170,234 @@ func New(config *rest.Config, opts Options) (Cache, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
transformByGVK, err := convertToTransformByKindAndGVK(opts.TransformByObject, opts.DefaultTransform, opts.Scheme)
|
||||
transformByGVK, err := convertToByGVK(opts.TransformByObject, opts.DefaultTransform, opts.Scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
transformByObj := internal.TransformFuncByObjectFromMap(transformByGVK)
|
||||
|
||||
internalSelectorsByGVK := internal.SelectorsByGVK{}
|
||||
for gvk, selector := range selectorsByGVK {
|
||||
internalSelectorsByGVK[gvk] = internal.Selector(selector)
|
||||
}
|
||||
|
||||
im := internal.NewInformersMap(config, opts.Scheme, opts.Mapper, *opts.Resync, opts.Namespace, internalSelectorsByGVK, disableDeepCopyByGVK, transformByObj)
|
||||
return &informerCache{InformersMap: im}, nil
|
||||
}
|
||||
|
||||
// BuilderWithOptions returns a Cache constructor that will build a cache
|
||||
// honoring the options argument, this is useful to specify options like
|
||||
// SelectorsByObject
|
||||
// WARNING: If SelectorsByObject is specified, filtered out resources are not
|
||||
// returned.
|
||||
// WARNING: If UnsafeDisableDeepCopy is enabled, you must DeepCopy any object
|
||||
// returned from cache get/list before mutating it.
|
||||
func BuilderWithOptions(options Options) NewCacheFunc {
|
||||
return func(config *rest.Config, inherited Options) (Cache, error) {
|
||||
var err error
|
||||
inherited, err = defaultOpts(config, inherited)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
options, err = defaultOpts(config, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
combined, err := options.inheritFrom(inherited)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return New(config, *combined)
|
||||
}
|
||||
}
|
||||
|
||||
func (options Options) inheritFrom(inherited Options) (*Options, error) {
|
||||
var (
|
||||
combined Options
|
||||
err error
|
||||
)
|
||||
combined.Scheme = combineScheme(inherited.Scheme, options.Scheme)
|
||||
combined.Mapper = selectMapper(inherited.Mapper, options.Mapper)
|
||||
combined.Resync = selectResync(inherited.Resync, options.Resync)
|
||||
combined.Namespace = selectNamespace(inherited.Namespace, options.Namespace)
|
||||
combined.SelectorsByObject, combined.DefaultSelector, err = combineSelectors(inherited, options, combined.Scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
combined.UnsafeDisableDeepCopyByObject, err = combineUnsafeDeepCopy(inherited, options, combined.Scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
combined.TransformByObject, combined.DefaultTransform, err = combineTransforms(inherited, options, combined.Scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &combined, nil
|
||||
}
|
||||
|
||||
func combineScheme(schemes ...*runtime.Scheme) *runtime.Scheme {
|
||||
var out *runtime.Scheme
|
||||
for _, sch := range schemes {
|
||||
if sch == nil {
|
||||
continue
|
||||
}
|
||||
for gvk, t := range sch.AllKnownTypes() {
|
||||
if out == nil {
|
||||
out = runtime.NewScheme()
|
||||
}
|
||||
out.AddKnownTypeWithName(gvk, reflect.New(t).Interface().(runtime.Object))
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func selectMapper(def, override meta.RESTMapper) meta.RESTMapper {
|
||||
if override != nil {
|
||||
return override
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
func selectResync(def, override *time.Duration) *time.Duration {
|
||||
if override != nil {
|
||||
return override
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
func selectNamespace(def, override string) string {
|
||||
if override != "" {
|
||||
return override
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
func combineSelectors(inherited, options Options, scheme *runtime.Scheme) (SelectorsByObject, ObjectSelector, error) {
|
||||
// Selectors are combined via logical AND.
|
||||
// - Combined label selector is a union of the selectors requirements from both sets of options.
|
||||
// - Combined field selector uses fields.AndSelectors with the combined list of non-nil field selectors
|
||||
// defined in both sets of options.
|
||||
//
|
||||
// There is a bunch of complexity here because we need to convert to SelectorsByGVK
|
||||
// to be able to match keys between options and inherited and then convert back to SelectorsByObject
|
||||
optionsSelectorsByGVK, err := convertToByGVK(options.SelectorsByObject, options.DefaultSelector, scheme)
|
||||
if err != nil {
|
||||
return nil, ObjectSelector{}, err
|
||||
}
|
||||
inheritedSelectorsByGVK, err := convertToByGVK(inherited.SelectorsByObject, inherited.DefaultSelector, inherited.Scheme)
|
||||
if err != nil {
|
||||
return nil, ObjectSelector{}, err
|
||||
}
|
||||
|
||||
for gvk, inheritedSelector := range inheritedSelectorsByGVK {
|
||||
optionsSelectorsByGVK[gvk] = combineSelector(inheritedSelector, optionsSelectorsByGVK[gvk])
|
||||
}
|
||||
return convertToByObject(optionsSelectorsByGVK, scheme)
|
||||
}
|
||||
|
||||
func combineSelector(selectors ...ObjectSelector) ObjectSelector {
|
||||
ls := make([]labels.Selector, 0, len(selectors))
|
||||
fs := make([]fields.Selector, 0, len(selectors))
|
||||
for _, s := range selectors {
|
||||
ls = append(ls, s.Label)
|
||||
fs = append(fs, s.Field)
|
||||
}
|
||||
return ObjectSelector{
|
||||
Label: combineLabelSelectors(ls...),
|
||||
Field: combineFieldSelectors(fs...),
|
||||
}
|
||||
}
|
||||
|
||||
func combineLabelSelectors(ls ...labels.Selector) labels.Selector {
|
||||
var combined labels.Selector
|
||||
for _, l := range ls {
|
||||
if l == nil {
|
||||
continue
|
||||
}
|
||||
if combined == nil {
|
||||
combined = labels.NewSelector()
|
||||
}
|
||||
reqs, _ := l.Requirements()
|
||||
combined = combined.Add(reqs...)
|
||||
}
|
||||
return combined
|
||||
}
|
||||
|
||||
func combineFieldSelectors(fs ...fields.Selector) fields.Selector {
|
||||
nonNil := fs[:0]
|
||||
for _, f := range fs {
|
||||
if f == nil {
|
||||
continue
|
||||
}
|
||||
nonNil = append(nonNil, f)
|
||||
}
|
||||
if len(nonNil) == 0 {
|
||||
return nil
|
||||
}
|
||||
if len(nonNil) == 1 {
|
||||
return nonNil[0]
|
||||
}
|
||||
return fields.AndSelectors(nonNil...)
|
||||
}
|
||||
|
||||
func combineUnsafeDeepCopy(inherited, options Options, scheme *runtime.Scheme) (DisableDeepCopyByObject, error) {
|
||||
// UnsafeDisableDeepCopyByObject is combined via precedence. Only if a value for a particular GVK is unset
|
||||
// in options will a value from inherited be used.
|
||||
optionsDisableDeepCopyByGVK, err := convertToDisableDeepCopyByGVK(options.UnsafeDisableDeepCopyByObject, options.Scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
inheritedDisableDeepCopyByGVK, err := convertToDisableDeepCopyByGVK(inherited.UnsafeDisableDeepCopyByObject, inherited.Scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
im := internal.NewInformersMap(config, opts.Scheme, opts.Mapper, *opts.Resync, opts.Namespace, selectorsByGVK, disableDeepCopyByGVK, transformByGVK)
|
||||
return &informerCache{InformersMap: im}, nil
|
||||
for gvk, inheritedDeepCopy := range inheritedDisableDeepCopyByGVK {
|
||||
if _, ok := optionsDisableDeepCopyByGVK[gvk]; !ok {
|
||||
if optionsDisableDeepCopyByGVK == nil {
|
||||
optionsDisableDeepCopyByGVK = map[schema.GroupVersionKind]bool{}
|
||||
}
|
||||
optionsDisableDeepCopyByGVK[gvk] = inheritedDeepCopy
|
||||
}
|
||||
}
|
||||
return convertToDisableDeepCopyByObject(optionsDisableDeepCopyByGVK, scheme)
|
||||
}
|
||||
|
||||
// BuilderWithOptions returns a Cache constructor that will build the a cache
|
||||
// honoring the options argument, this is useful to specify options like
|
||||
// SelectorsByObject
|
||||
// WARNING: if SelectorsByObject is specified. filtered out resources are not
|
||||
// returned.
|
||||
// WARNING: if UnsafeDisableDeepCopy is enabled, you must DeepCopy any object
|
||||
// returned from cache get/list before mutating it.
|
||||
func BuilderWithOptions(options Options) NewCacheFunc {
|
||||
return func(config *rest.Config, opts Options) (Cache, error) {
|
||||
if options.Scheme == nil {
|
||||
options.Scheme = opts.Scheme
|
||||
}
|
||||
if options.Mapper == nil {
|
||||
options.Mapper = opts.Mapper
|
||||
}
|
||||
if options.Resync == nil {
|
||||
options.Resync = opts.Resync
|
||||
}
|
||||
if options.Namespace == "" {
|
||||
options.Namespace = opts.Namespace
|
||||
}
|
||||
if opts.Resync == nil {
|
||||
opts.Resync = options.Resync
|
||||
}
|
||||
func combineTransforms(inherited, options Options, scheme *runtime.Scheme) (TransformByObject, toolscache.TransformFunc, error) {
|
||||
// Transform functions are combined via chaining. If both inherited and options define a transform
|
||||
// function, the transform function from inherited will be called first, and the transform function from
|
||||
// options will be called second.
|
||||
optionsTransformByGVK, err := convertToByGVK(options.TransformByObject, options.DefaultTransform, options.Scheme)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
inheritedTransformByGVK, err := convertToByGVK(inherited.TransformByObject, inherited.DefaultTransform, inherited.Scheme)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return New(config, options)
|
||||
for gvk, inheritedTransform := range inheritedTransformByGVK {
|
||||
if optionsTransformByGVK == nil {
|
||||
optionsTransformByGVK = map[schema.GroupVersionKind]toolscache.TransformFunc{}
|
||||
}
|
||||
optionsTransformByGVK[gvk] = combineTransform(inheritedTransform, optionsTransformByGVK[gvk])
|
||||
}
|
||||
return convertToByObject(optionsTransformByGVK, scheme)
|
||||
}
|
||||
|
||||
func combineTransform(inherited, current toolscache.TransformFunc) toolscache.TransformFunc {
|
||||
if inherited == nil {
|
||||
return current
|
||||
}
|
||||
if current == nil {
|
||||
return inherited
|
||||
}
|
||||
return func(in interface{}) (interface{}, error) {
|
||||
mid, err := inherited(in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return current(mid)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,17 +424,40 @@ func defaultOpts(config *rest.Config, opts Options) (Options, error) {
|
||||
return opts, nil
|
||||
}
|
||||
|
||||
func convertToSelectorsByGVK(selectorsByObject SelectorsByObject, defaultSelector ObjectSelector, scheme *runtime.Scheme) (internal.SelectorsByGVK, error) {
|
||||
selectorsByGVK := internal.SelectorsByGVK{}
|
||||
for object, selector := range selectorsByObject {
|
||||
func convertToByGVK[T any](byObject map[client.Object]T, def T, scheme *runtime.Scheme) (map[schema.GroupVersionKind]T, error) {
|
||||
byGVK := map[schema.GroupVersionKind]T{}
|
||||
for object, value := range byObject {
|
||||
gvk, err := apiutil.GVKForObject(object, scheme)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selectorsByGVK[gvk] = internal.Selector(selector)
|
||||
byGVK[gvk] = value
|
||||
}
|
||||
selectorsByGVK[schema.GroupVersionKind{}] = internal.Selector(defaultSelector)
|
||||
return selectorsByGVK, nil
|
||||
byGVK[schema.GroupVersionKind{}] = def
|
||||
return byGVK, nil
|
||||
}
|
||||
|
||||
func convertToByObject[T any](byGVK map[schema.GroupVersionKind]T, scheme *runtime.Scheme) (map[client.Object]T, T, error) {
|
||||
var byObject map[client.Object]T
|
||||
def := byGVK[schema.GroupVersionKind{}]
|
||||
for gvk, value := range byGVK {
|
||||
if gvk == (schema.GroupVersionKind{}) {
|
||||
continue
|
||||
}
|
||||
obj, err := scheme.New(gvk)
|
||||
if err != nil {
|
||||
return nil, def, err
|
||||
}
|
||||
cObj, ok := obj.(client.Object)
|
||||
if !ok {
|
||||
return nil, def, fmt.Errorf("object %T for GVK %q does not implement client.Object", obj, gvk)
|
||||
}
|
||||
if byObject == nil {
|
||||
byObject = map[client.Object]T{}
|
||||
}
|
||||
byObject[cObj] = value
|
||||
}
|
||||
return byObject, def, nil
|
||||
}
|
||||
|
||||
// DisableDeepCopyByObject associate a client.Object's GVK to disable DeepCopy during get or list from cache.
|
||||
@@ -259,17 +487,30 @@ func convertToDisableDeepCopyByGVK(disableDeepCopyByObject DisableDeepCopyByObje
|
||||
return disableDeepCopyByGVK, nil
|
||||
}
|
||||
|
||||
func convertToDisableDeepCopyByObject(byGVK internal.DisableDeepCopyByGVK, scheme *runtime.Scheme) (DisableDeepCopyByObject, error) {
|
||||
var byObject DisableDeepCopyByObject
|
||||
for gvk, value := range byGVK {
|
||||
if byObject == nil {
|
||||
byObject = DisableDeepCopyByObject{}
|
||||
}
|
||||
if gvk == (schema.GroupVersionKind{}) {
|
||||
byObject[ObjectAll{}] = value
|
||||
continue
|
||||
}
|
||||
obj, err := scheme.New(gvk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cObj, ok := obj.(client.Object)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("object %T for GVK %q does not implement client.Object", obj, gvk)
|
||||
}
|
||||
|
||||
byObject[cObj] = value
|
||||
}
|
||||
return byObject, nil
|
||||
}
|
||||
|
||||
// TransformByObject associate a client.Object's GVK to a transformer function
|
||||
// to be applied when storing the object into the cache.
|
||||
type TransformByObject map[client.Object]toolscache.TransformFunc
|
||||
|
||||
func convertToTransformByKindAndGVK(t TransformByObject, defaultTransform toolscache.TransformFunc, scheme *runtime.Scheme) (internal.TransformFuncByObject, error) {
|
||||
result := internal.NewTransformFuncByObject()
|
||||
for obj, transformation := range t {
|
||||
if err := result.Set(obj, scheme, transformation); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
result.SetDefault(defaultTransform)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
2
vendor/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache.go
generated
vendored
2
vendor/sigs.k8s.io/controller-runtime/pkg/cache/informer_cache.go
generated
vendored
@@ -51,7 +51,7 @@ type informerCache struct {
|
||||
}
|
||||
|
||||
// Get implements Reader.
|
||||
func (ip *informerCache) Get(ctx context.Context, key client.ObjectKey, out client.Object) error {
|
||||
func (ip *informerCache) Get(ctx context.Context, key client.ObjectKey, out client.Object, opts ...client.GetOption) error {
|
||||
gvk, err := apiutil.GVKForObject(out, ip.Scheme)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
22
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/cache_reader.go
generated
vendored
22
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/cache_reader.go
generated
vendored
@@ -23,12 +23,11 @@ import (
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/selection"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"sigs.k8s.io/controller-runtime/pkg/internal/field/selector"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
@@ -54,7 +53,7 @@ type CacheReader struct {
|
||||
}
|
||||
|
||||
// Get checks the indexer for the object and writes a copy of it if found.
|
||||
func (c *CacheReader) Get(_ context.Context, key client.ObjectKey, out client.Object) error {
|
||||
func (c *CacheReader) Get(_ context.Context, key client.ObjectKey, out client.Object, opts ...client.GetOption) error {
|
||||
if c.scopeName == apimeta.RESTScopeNameRoot {
|
||||
key.Namespace = ""
|
||||
}
|
||||
@@ -116,7 +115,7 @@ func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...cli
|
||||
case listOpts.FieldSelector != nil:
|
||||
// TODO(directxman12): support more complicated field selectors by
|
||||
// combining multiple indices, GetIndexers, etc
|
||||
field, val, requiresExact := requiresExactMatch(listOpts.FieldSelector)
|
||||
field, val, requiresExact := selector.RequiresExactMatch(listOpts.FieldSelector)
|
||||
if !requiresExact {
|
||||
return fmt.Errorf("non-exact field matches are not supported by the cache")
|
||||
}
|
||||
@@ -162,7 +161,7 @@ func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...cli
|
||||
}
|
||||
|
||||
var outObj runtime.Object
|
||||
if c.disableDeepCopy {
|
||||
if c.disableDeepCopy || (listOpts.UnsafeDisableDeepCopy != nil && *listOpts.UnsafeDisableDeepCopy) {
|
||||
// skip deep copy which might be unsafe
|
||||
// you must DeepCopy any object before mutating it outside
|
||||
outObj = obj
|
||||
@@ -186,19 +185,6 @@ func objectKeyToStoreKey(k client.ObjectKey) string {
|
||||
return k.Namespace + "/" + k.Name
|
||||
}
|
||||
|
||||
// requiresExactMatch checks if the given field selector is of the form `k=v` or `k==v`.
|
||||
func requiresExactMatch(sel fields.Selector) (field, val string, required bool) {
|
||||
reqs := sel.Requirements()
|
||||
if len(reqs) != 1 {
|
||||
return "", "", false
|
||||
}
|
||||
req := reqs[0]
|
||||
if req.Operator != selection.Equals && req.Operator != selection.DoubleEquals {
|
||||
return "", "", false
|
||||
}
|
||||
return req.Field, req.Value, true
|
||||
}
|
||||
|
||||
// FieldIndexName constructs the name of the index over the given field,
|
||||
// for use with an indexer.
|
||||
func FieldIndexName(field string) string {
|
||||
|
||||
15
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/transformers.go
generated
vendored
15
vendor/sigs.k8s.io/controller-runtime/pkg/cache/internal/transformers.go
generated
vendored
@@ -4,6 +4,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||
)
|
||||
|
||||
@@ -20,12 +21,16 @@ type transformFuncByGVK struct {
|
||||
transformers map[schema.GroupVersionKind]cache.TransformFunc
|
||||
}
|
||||
|
||||
// NewTransformFuncByObject creates a new TransformFuncByObject instance.
|
||||
func NewTransformFuncByObject() TransformFuncByObject {
|
||||
return &transformFuncByGVK{
|
||||
transformers: make(map[schema.GroupVersionKind]cache.TransformFunc),
|
||||
defaultTransform: nil,
|
||||
// TransformFuncByObjectFromMap creates a TransformFuncByObject from a map that
|
||||
// maps GVKs to TransformFuncs.
|
||||
func TransformFuncByObjectFromMap(in map[schema.GroupVersionKind]cache.TransformFunc) TransformFuncByObject {
|
||||
byGVK := &transformFuncByGVK{}
|
||||
if defaultFunc, hasDefault := in[schema.GroupVersionKind{}]; hasDefault {
|
||||
byGVK.defaultTransform = defaultFunc
|
||||
}
|
||||
delete(in, schema.GroupVersionKind{})
|
||||
byGVK.transformers = in
|
||||
return byGVK
|
||||
}
|
||||
|
||||
func (t *transformFuncByGVK) SetDefault(transformer cache.TransformFunc) {
|
||||
|
||||
44
vendor/sigs.k8s.io/controller-runtime/pkg/cache/multi_namespace_cache.go
generated
vendored
44
vendor/sigs.k8s.io/controller-runtime/pkg/cache/multi_namespace_cache.go
generated
vendored
@@ -200,7 +200,7 @@ func (c *multiNamespaceCache) IndexField(ctx context.Context, obj client.Object,
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *multiNamespaceCache) Get(ctx context.Context, key client.ObjectKey, obj client.Object) error {
|
||||
func (c *multiNamespaceCache) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error {
|
||||
isNamespaced, err := objectutil.IsAPINamespaced(obj, c.Scheme, c.RESTMapper)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -296,17 +296,47 @@ type multiNamespaceInformer struct {
|
||||
var _ Informer = &multiNamespaceInformer{}
|
||||
|
||||
// AddEventHandler adds the handler to each namespaced informer.
|
||||
func (i *multiNamespaceInformer) AddEventHandler(handler toolscache.ResourceEventHandler) {
|
||||
for _, informer := range i.namespaceToInformer {
|
||||
informer.AddEventHandler(handler)
|
||||
func (i *multiNamespaceInformer) AddEventHandler(handler toolscache.ResourceEventHandler) (toolscache.ResourceEventHandlerRegistration, error) {
|
||||
handles := make(map[string]toolscache.ResourceEventHandlerRegistration, len(i.namespaceToInformer))
|
||||
for ns, informer := range i.namespaceToInformer {
|
||||
registration, err := informer.AddEventHandler(handler)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
handles[ns] = registration
|
||||
}
|
||||
return handles, nil
|
||||
}
|
||||
|
||||
// AddEventHandlerWithResyncPeriod adds the handler with a resync period to each namespaced informer.
|
||||
func (i *multiNamespaceInformer) AddEventHandlerWithResyncPeriod(handler toolscache.ResourceEventHandler, resyncPeriod time.Duration) {
|
||||
for _, informer := range i.namespaceToInformer {
|
||||
informer.AddEventHandlerWithResyncPeriod(handler, resyncPeriod)
|
||||
func (i *multiNamespaceInformer) AddEventHandlerWithResyncPeriod(handler toolscache.ResourceEventHandler, resyncPeriod time.Duration) (toolscache.ResourceEventHandlerRegistration, error) {
|
||||
handles := make(map[string]toolscache.ResourceEventHandlerRegistration, len(i.namespaceToInformer))
|
||||
for ns, informer := range i.namespaceToInformer {
|
||||
registration, err := informer.AddEventHandlerWithResyncPeriod(handler, resyncPeriod)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
handles[ns] = registration
|
||||
}
|
||||
return handles, nil
|
||||
}
|
||||
|
||||
// RemoveEventHandler removes a formerly added event handler given by its registration handle.
|
||||
func (i *multiNamespaceInformer) RemoveEventHandler(h toolscache.ResourceEventHandlerRegistration) error {
|
||||
handles, ok := h.(map[string]toolscache.ResourceEventHandlerRegistration)
|
||||
if !ok {
|
||||
return fmt.Errorf("it is not the registration returned by multiNamespaceInformer")
|
||||
}
|
||||
for ns, informer := range i.namespaceToInformer {
|
||||
registration, ok := handles[ns]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if err := informer.RemoveEventHandler(registration); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddIndexers adds the indexer for each namespaced informer.
|
||||
|
||||
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
|
||||
|
||||
42
vendor/sigs.k8s.io/controller-runtime/pkg/cluster/cluster.go
generated
vendored
42
vendor/sigs.k8s.io/controller-runtime/pkg/cluster/cluster.go
generated
vendored
@@ -112,6 +112,7 @@ type Options struct {
|
||||
// NewClient is the func that creates the client to be used by the manager.
|
||||
// If not set this will create the default DelegatingClient that will
|
||||
// use the cache for reads and the client for writes.
|
||||
// NOTE: The default client will not cache Unstructured.
|
||||
NewClient NewClientFunc
|
||||
|
||||
// ClientDisableCacheFor tells the client that, if any cache is used, to bypass it
|
||||
@@ -255,16 +256,33 @@ func setOptionsDefaults(options Options) Options {
|
||||
// NewClientFunc allows a user to define how to create a client.
|
||||
type NewClientFunc func(cache cache.Cache, config *rest.Config, options client.Options, uncachedObjects ...client.Object) (client.Client, error)
|
||||
|
||||
// DefaultNewClient creates the default caching client.
|
||||
func DefaultNewClient(cache cache.Cache, config *rest.Config, options client.Options, uncachedObjects ...client.Object) (client.Client, error) {
|
||||
c, err := client.New(config, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return client.NewDelegatingClient(client.NewDelegatingClientInput{
|
||||
CacheReader: cache,
|
||||
Client: c,
|
||||
UncachedObjects: uncachedObjects,
|
||||
})
|
||||
// ClientOptions are the optional arguments for tuning the caching client.
|
||||
type ClientOptions struct {
|
||||
UncachedObjects []client.Object
|
||||
CacheUnstructured bool
|
||||
}
|
||||
|
||||
// DefaultNewClient creates the default caching client, that will never cache Unstructured.
|
||||
func DefaultNewClient(cache cache.Cache, config *rest.Config, options client.Options, uncachedObjects ...client.Object) (client.Client, error) {
|
||||
return ClientBuilderWithOptions(ClientOptions{})(cache, config, options, uncachedObjects...)
|
||||
}
|
||||
|
||||
// ClientBuilderWithOptions returns a Client constructor that will build a client
|
||||
// honoring the options argument
|
||||
func ClientBuilderWithOptions(options ClientOptions) NewClientFunc {
|
||||
return func(cache cache.Cache, config *rest.Config, clientOpts client.Options, uncachedObjects ...client.Object) (client.Client, error) {
|
||||
options.UncachedObjects = append(options.UncachedObjects, uncachedObjects...)
|
||||
|
||||
c, err := client.New(config, clientOpts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return client.NewDelegatingClient(client.NewDelegatingClientInput{
|
||||
CacheReader: cache,
|
||||
Client: c,
|
||||
UncachedObjects: options.UncachedObjects,
|
||||
CacheUnstructured: options.CacheUnstructured,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
26
vendor/sigs.k8s.io/controller-runtime/pkg/config/config.go
generated
vendored
26
vendor/sigs.k8s.io/controller-runtime/pkg/config/config.go
generated
vendored
@@ -24,20 +24,24 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/config/v1alpha1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/config/v1alpha1" //nolint:staticcheck
|
||||
)
|
||||
|
||||
// ControllerManagerConfiguration defines the functions necessary to parse a config file
|
||||
// and to configure the Options struct for the ctrl.Manager.
|
||||
//
|
||||
// Deprecated: This package has been deprecated and will be removed in a future release.
|
||||
type ControllerManagerConfiguration interface {
|
||||
runtime.Object
|
||||
|
||||
// Complete returns the versioned configuration
|
||||
Complete() (v1alpha1.ControllerManagerConfigurationSpec, error)
|
||||
Complete() (v1alpha1.ControllerManagerConfigurationSpec, error) //nolint:staticcheck
|
||||
}
|
||||
|
||||
// DeferredFileLoader is used to configure the decoder for loading controller
|
||||
// runtime component config types.
|
||||
//
|
||||
// Deprecated: This package has been deprecated and will be removed in a future release.
|
||||
type DeferredFileLoader struct {
|
||||
ControllerManagerConfiguration
|
||||
path string
|
||||
@@ -50,8 +54,10 @@ type DeferredFileLoader struct {
|
||||
// this will also configure the defaults for the loader if nothing is
|
||||
//
|
||||
// Defaults:
|
||||
// Path: "./config.yaml"
|
||||
// Kind: GenericControllerManagerConfiguration
|
||||
// * Path: "./config.yaml"
|
||||
// * Kind: GenericControllerManagerConfiguration
|
||||
//
|
||||
// Deprecated: This package has been deprecated and will be removed in a future release.
|
||||
func File() *DeferredFileLoader {
|
||||
scheme := runtime.NewScheme()
|
||||
utilruntime.Must(v1alpha1.AddToScheme(scheme))
|
||||
@@ -63,6 +69,8 @@ func File() *DeferredFileLoader {
|
||||
}
|
||||
|
||||
// Complete will use sync.Once to set the scheme.
|
||||
//
|
||||
// Deprecated: This package has been deprecated and will be removed in a future release.
|
||||
func (d *DeferredFileLoader) Complete() (v1alpha1.ControllerManagerConfigurationSpec, error) {
|
||||
d.once.Do(d.loadFile)
|
||||
if d.err != nil {
|
||||
@@ -71,25 +79,33 @@ func (d *DeferredFileLoader) Complete() (v1alpha1.ControllerManagerConfiguration
|
||||
return d.ControllerManagerConfiguration.Complete()
|
||||
}
|
||||
|
||||
// AtPath will set the path to load the file for the decoder.
|
||||
// AtPath will set the path to load the file for the decoder
|
||||
//
|
||||
// Deprecated: This package has been deprecated and will be removed in a future release.
|
||||
func (d *DeferredFileLoader) AtPath(path string) *DeferredFileLoader {
|
||||
d.path = path
|
||||
return d
|
||||
}
|
||||
|
||||
// OfKind will set the type to be used for decoding the file into.
|
||||
//
|
||||
// Deprecated: This package has been deprecated and will be removed in a future release.
|
||||
func (d *DeferredFileLoader) OfKind(obj ControllerManagerConfiguration) *DeferredFileLoader {
|
||||
d.ControllerManagerConfiguration = obj
|
||||
return d
|
||||
}
|
||||
|
||||
// InjectScheme will configure the scheme to be used for decoding the file.
|
||||
//
|
||||
// Deprecated: This package has been deprecated and will be removed in a future release.
|
||||
func (d *DeferredFileLoader) InjectScheme(scheme *runtime.Scheme) error {
|
||||
d.scheme = scheme
|
||||
return nil
|
||||
}
|
||||
|
||||
// loadFile is used from the mutex.Once to load the file.
|
||||
//
|
||||
// Deprecated: This package has been deprecated and will be removed in a future release.
|
||||
func (d *DeferredFileLoader) loadFile() {
|
||||
if d.scheme == nil {
|
||||
d.err = fmt.Errorf("scheme not supplied to controller configuration loader")
|
||||
|
||||
4
vendor/sigs.k8s.io/controller-runtime/pkg/config/doc.go
generated
vendored
4
vendor/sigs.k8s.io/controller-runtime/pkg/config/doc.go
generated
vendored
@@ -17,9 +17,11 @@ limitations under the License.
|
||||
// Package config contains functionality for interacting with ComponentConfig
|
||||
// files
|
||||
//
|
||||
// DeferredFileLoader
|
||||
// # DeferredFileLoader
|
||||
//
|
||||
// This uses a deferred file decoding allowing you to chain your configuration
|
||||
// setup. You can pass this into manager.Options#File and it will load your
|
||||
// config.
|
||||
//
|
||||
// Deprecated: This package has been deprecated and will be removed in a future release.
|
||||
package config
|
||||
|
||||
2
vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/doc.go
generated
vendored
2
vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/doc.go
generated
vendored
@@ -17,4 +17,6 @@ limitations under the License.
|
||||
// Package v1alpha1 provides the ControllerManagerConfiguration used for
|
||||
// configuring ctrl.Manager
|
||||
// +kubebuilder:object:generate=true
|
||||
//
|
||||
// Deprecated: This package has been deprecated and will be removed in a future release.
|
||||
package v1alpha1
|
||||
|
||||
6
vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/register.go
generated
vendored
6
vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/register.go
generated
vendored
@@ -23,12 +23,18 @@ import (
|
||||
|
||||
var (
|
||||
// GroupVersion is group version used to register these objects.
|
||||
//
|
||||
// Deprecated: This package has been deprecated and will be removed in a future release.
|
||||
GroupVersion = schema.GroupVersion{Group: "controller-runtime.sigs.k8s.io", Version: "v1alpha1"}
|
||||
|
||||
// SchemeBuilder is used to add go types to the GroupVersionKind scheme.
|
||||
//
|
||||
// Deprecated: This package has been deprecated and will be removed in a future release.
|
||||
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
|
||||
|
||||
// AddToScheme adds the types in this group-version to the given scheme.
|
||||
//
|
||||
// Deprecated: This package has been deprecated and will be removed in a future release.
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
|
||||
15
vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/types.go
generated
vendored
15
vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/types.go
generated
vendored
@@ -25,6 +25,8 @@ import (
|
||||
)
|
||||
|
||||
// ControllerManagerConfigurationSpec defines the desired state of GenericControllerManagerConfiguration.
|
||||
//
|
||||
// Deprecated: This package has been deprecated and will be removed in a future release.
|
||||
type ControllerManagerConfigurationSpec struct {
|
||||
// SyncPeriod determines the minimum frequency at which watched resources are
|
||||
// reconciled. A lower period will correct entropy more quickly, but reduce
|
||||
@@ -75,6 +77,8 @@ type ControllerManagerConfigurationSpec struct {
|
||||
|
||||
// ControllerConfigurationSpec defines the global configuration for
|
||||
// controllers registered with the manager.
|
||||
//
|
||||
// Deprecated: This package has been deprecated and will be removed in a future release.
|
||||
type ControllerConfigurationSpec struct {
|
||||
// GroupKindConcurrency is a map from a Kind to the number of concurrent reconciliation
|
||||
// allowed for that controller.
|
||||
@@ -94,6 +98,10 @@ type ControllerConfigurationSpec struct {
|
||||
// Defaults to 2 minutes if not set.
|
||||
// +optional
|
||||
CacheSyncTimeout *time.Duration `json:"cacheSyncTimeout,omitempty"`
|
||||
|
||||
// RecoverPanic indicates if panics should be recovered.
|
||||
// +optional
|
||||
RecoverPanic *bool `json:"recoverPanic,omitempty"`
|
||||
}
|
||||
|
||||
// ControllerMetrics defines the metrics configs.
|
||||
@@ -109,6 +117,7 @@ type ControllerMetrics struct {
|
||||
type ControllerHealth struct {
|
||||
// HealthProbeBindAddress is the TCP address that the controller should bind to
|
||||
// for serving health probes
|
||||
// It can be set to "0" or "" to disable serving the health probe.
|
||||
// +optional
|
||||
HealthProbeBindAddress string `json:"healthProbeBindAddress,omitempty"`
|
||||
|
||||
@@ -144,14 +153,20 @@ type ControllerWebhook struct {
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// ControllerManagerConfiguration is the Schema for the GenericControllerManagerConfigurations API.
|
||||
//
|
||||
// Deprecated: This package has been deprecated and will be removed in a future release.
|
||||
type ControllerManagerConfiguration struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// ControllerManagerConfiguration returns the contfigurations for controllers
|
||||
//
|
||||
// Deprecated: This package has been deprecated and will be removed in a future release.
|
||||
ControllerManagerConfigurationSpec `json:",inline"`
|
||||
}
|
||||
|
||||
// Complete returns the configuration for controller-runtime.
|
||||
//
|
||||
// Deprecated: This package has been deprecated and will be removed in a future release.
|
||||
func (c *ControllerManagerConfigurationSpec) Complete() (ControllerManagerConfigurationSpec, error) {
|
||||
return *c, nil
|
||||
}
|
||||
|
||||
5
vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/zz_generated.deepcopy.go
generated
vendored
5
vendor/sigs.k8s.io/controller-runtime/pkg/config/v1alpha1/zz_generated.deepcopy.go
generated
vendored
@@ -27,6 +27,11 @@ func (in *ControllerConfigurationSpec) DeepCopyInto(out *ControllerConfiguration
|
||||
*out = new(timex.Duration)
|
||||
**out = **in
|
||||
}
|
||||
if in.RecoverPanic != nil {
|
||||
in, out := &in.RecoverPanic, &out.RecoverPanic
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControllerConfigurationSpec.
|
||||
|
||||
10
vendor/sigs.k8s.io/controller-runtime/pkg/controller/controller.go
generated
vendored
10
vendor/sigs.k8s.io/controller-runtime/pkg/controller/controller.go
generated
vendored
@@ -56,7 +56,8 @@ type Options struct {
|
||||
CacheSyncTimeout time.Duration
|
||||
|
||||
// RecoverPanic indicates whether the panic caused by reconcile should be recovered.
|
||||
RecoverPanic bool
|
||||
// Defaults to the Controller.RecoverPanic setting from the Manager if unset.
|
||||
RecoverPanic *bool
|
||||
}
|
||||
|
||||
// Controller implements a Kubernetes API. A Controller manages a work queue fed reconcile.Requests
|
||||
@@ -139,6 +140,10 @@ func NewUnmanaged(name string, mgr manager.Manager, options Options) (Controller
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if options.RecoverPanic == nil {
|
||||
options.RecoverPanic = mgr.GetControllerOptions().RecoverPanic //nolint:staticcheck
|
||||
}
|
||||
|
||||
// Create controller with dependencies set
|
||||
return &controller.Controller{
|
||||
Do: options.Reconciler,
|
||||
@@ -153,3 +158,6 @@ func NewUnmanaged(name string, mgr manager.Manager, options Options) (Controller
|
||||
RecoverPanic: options.RecoverPanic,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ReconcileIDFromContext gets the reconcileID from the current context.
|
||||
var ReconcileIDFromContext = controller.ReconcileIDFromContext
|
||||
|
||||
@@ -76,8 +76,8 @@ func SetControllerReference(owner, controlled metav1.Object, scheme *runtime.Sch
|
||||
Kind: gvk.Kind,
|
||||
Name: owner.GetName(),
|
||||
UID: owner.GetUID(),
|
||||
BlockOwnerDeletion: pointer.BoolPtr(true),
|
||||
Controller: pointer.BoolPtr(true),
|
||||
BlockOwnerDeletion: pointer.Bool(true),
|
||||
Controller: pointer.Bool(true),
|
||||
}
|
||||
|
||||
// Return early with an error if the object is already controlled.
|
||||
@@ -207,7 +207,7 @@ func CreateOrUpdate(ctx context.Context, c client.Client, obj client.Object, f M
|
||||
return OperationResultCreated, nil
|
||||
}
|
||||
|
||||
existing := obj.DeepCopyObject() //nolint
|
||||
existing := obj.DeepCopyObject()
|
||||
if err := mutate(f, key, obj); err != nil {
|
||||
return OperationResultNone, err
|
||||
}
|
||||
|
||||
2
vendor/sigs.k8s.io/controller-runtime/pkg/controller/doc.go
generated
vendored
2
vendor/sigs.k8s.io/controller-runtime/pkg/controller/doc.go
generated
vendored
@@ -17,7 +17,7 @@ limitations under the License.
|
||||
/*
|
||||
Package controller provides types and functions for building Controllers. Controllers implement Kubernetes APIs.
|
||||
|
||||
Creation
|
||||
# Creation
|
||||
|
||||
To create a new Controller, first create a manager.Manager and pass it to the controller.New function.
|
||||
The Controller MUST be started by calling Manager.Start.
|
||||
|
||||
14
vendor/sigs.k8s.io/controller-runtime/pkg/envtest/crd.go
generated
vendored
14
vendor/sigs.k8s.io/controller-runtime/pkg/envtest/crd.go
generated
vendored
@@ -84,8 +84,10 @@ type CRDInstallOptions struct {
|
||||
WebhookOptions WebhookInstallOptions
|
||||
}
|
||||
|
||||
const defaultPollInterval = 100 * time.Millisecond
|
||||
const defaultMaxWait = 10 * time.Second
|
||||
const (
|
||||
defaultPollInterval = 100 * time.Millisecond
|
||||
defaultMaxWait = 10 * time.Second
|
||||
)
|
||||
|
||||
// InstallCRDs installs a collection of CRDs into a cluster by reading the crd yaml files from a directory.
|
||||
func InstallCRDs(config *rest.Config, options CRDInstallOptions) ([]*apiextensionsv1.CustomResourceDefinition, error) {
|
||||
@@ -142,7 +144,7 @@ func defaultCRDOptions(o *CRDInstallOptions) {
|
||||
// WaitForCRDs waits for the CRDs to appear in discovery.
|
||||
func WaitForCRDs(config *rest.Config, crds []*apiextensionsv1.CustomResourceDefinition, options CRDInstallOptions) error {
|
||||
// Add each CRD to a map of GroupVersion to Resource
|
||||
waitingFor := map[schema.GroupVersion]*sets.String{}
|
||||
waitingFor := map[schema.GroupVersion]*sets.Set[string]{}
|
||||
for _, crd := range crds {
|
||||
gvs := []schema.GroupVersion{}
|
||||
for _, version := range crd.Spec.Versions {
|
||||
@@ -155,7 +157,7 @@ func WaitForCRDs(config *rest.Config, crds []*apiextensionsv1.CustomResourceDefi
|
||||
log.V(1).Info("adding API in waitlist", "GV", gv)
|
||||
if _, found := waitingFor[gv]; !found {
|
||||
// Initialize the set
|
||||
waitingFor[gv] = &sets.String{}
|
||||
waitingFor[gv] = &sets.Set[string]{}
|
||||
}
|
||||
// Add the Resource
|
||||
waitingFor[gv].Insert(crd.Spec.Names.Plural)
|
||||
@@ -173,7 +175,7 @@ type poller struct {
|
||||
config *rest.Config
|
||||
|
||||
// waitingFor is the map of resources keyed by group version that have not yet been found in discovery
|
||||
waitingFor map[schema.GroupVersion]*sets.String
|
||||
waitingFor map[schema.GroupVersion]*sets.Set[string]
|
||||
}
|
||||
|
||||
// poll checks if all the resources have been found in discovery, and returns false if not.
|
||||
@@ -362,7 +364,7 @@ func modifyConversionWebhooks(crds []*apiextensionsv1.CustomResourceDefinition,
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
url := pointer.StringPtr(fmt.Sprintf("https://%s/convert", hostPort))
|
||||
url := pointer.String(fmt.Sprintf("https://%s/convert", hostPort))
|
||||
|
||||
for i := range crds {
|
||||
// Continue if we're preserving unknown fields.
|
||||
|
||||
53
vendor/sigs.k8s.io/controller-runtime/pkg/envtest/printer/ginkgo.go
generated
vendored
53
vendor/sigs.k8s.io/controller-runtime/pkg/envtest/printer/ginkgo.go
generated
vendored
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package printer contains setup for a friendlier Ginkgo printer that's easier
|
||||
// to parse by test automation.
|
||||
package printer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/onsi/ginkgo"
|
||||
"github.com/onsi/ginkgo/config"
|
||||
"github.com/onsi/ginkgo/types"
|
||||
)
|
||||
|
||||
var _ ginkgo.Reporter = NewlineReporter{}
|
||||
|
||||
// NewlineReporter is Reporter that Prints a newline after the default Reporter output so that the results
|
||||
// are correctly parsed by test automation.
|
||||
// See issue https://github.com/jstemmer/go-junit-report/issues/31
|
||||
type NewlineReporter struct{}
|
||||
|
||||
// SpecSuiteWillBegin implements ginkgo.Reporter.
|
||||
func (NewlineReporter) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) {
|
||||
}
|
||||
|
||||
// BeforeSuiteDidRun implements ginkgo.Reporter.
|
||||
func (NewlineReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) {}
|
||||
|
||||
// AfterSuiteDidRun implements ginkgo.Reporter.
|
||||
func (NewlineReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) {}
|
||||
|
||||
// SpecWillRun implements ginkgo.Reporter.
|
||||
func (NewlineReporter) SpecWillRun(specSummary *types.SpecSummary) {}
|
||||
|
||||
// SpecDidComplete implements ginkgo.Reporter.
|
||||
func (NewlineReporter) SpecDidComplete(specSummary *types.SpecSummary) {}
|
||||
|
||||
// SpecSuiteDidEnd Prints a newline between "35 Passed | 0 Failed | 0 Pending | 0 Skipped" and "--- PASS:".
|
||||
func (NewlineReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) { fmt.Printf("\n") }
|
||||
109
vendor/sigs.k8s.io/controller-runtime/pkg/envtest/printer/prow.go
generated
vendored
109
vendor/sigs.k8s.io/controller-runtime/pkg/envtest/printer/prow.go
generated
vendored
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 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 printer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/onsi/ginkgo"
|
||||
"github.com/onsi/ginkgo/config"
|
||||
"github.com/onsi/ginkgo/reporters"
|
||||
"github.com/onsi/ginkgo/types"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
)
|
||||
|
||||
var (
|
||||
allRegisteredSuites = sets.String{}
|
||||
allRegisteredSuitesLock = &sync.Mutex{}
|
||||
)
|
||||
|
||||
type prowReporter struct {
|
||||
junitReporter *reporters.JUnitReporter
|
||||
}
|
||||
|
||||
// NewProwReporter returns a prowReporter that will write out junit if running in Prow and do
|
||||
// nothing otherwise.
|
||||
// WARNING: It seems this does not always properly fail the test runs when there are failures,
|
||||
// see https://github.com/onsi/ginkgo/issues/706
|
||||
// When using this you must make sure to grep for failures in your junit xmls and fail the run
|
||||
// if there are any.
|
||||
func NewProwReporter(suiteName string) ginkgo.Reporter {
|
||||
allRegisteredSuitesLock.Lock()
|
||||
if allRegisteredSuites.Has(suiteName) {
|
||||
panic(fmt.Sprintf("Suite named %q registered more than once", suiteName))
|
||||
}
|
||||
allRegisteredSuites.Insert(suiteName)
|
||||
allRegisteredSuitesLock.Unlock()
|
||||
|
||||
if os.Getenv("CI") == "" {
|
||||
return &prowReporter{}
|
||||
}
|
||||
artifactsDir := os.Getenv("ARTIFACTS")
|
||||
if artifactsDir == "" {
|
||||
return &prowReporter{}
|
||||
}
|
||||
|
||||
path := filepath.Join(artifactsDir, fmt.Sprintf("junit_%s_%d.xml", suiteName, config.GinkgoConfig.ParallelNode))
|
||||
return &prowReporter{
|
||||
junitReporter: reporters.NewJUnitReporter(path),
|
||||
}
|
||||
}
|
||||
|
||||
func (pr *prowReporter) SpecSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary) {
|
||||
if pr.junitReporter != nil {
|
||||
pr.junitReporter.SpecSuiteWillBegin(config, summary)
|
||||
}
|
||||
}
|
||||
|
||||
// BeforeSuiteDidRun implements ginkgo.Reporter.
|
||||
func (pr *prowReporter) BeforeSuiteDidRun(setupSummary *types.SetupSummary) {
|
||||
if pr.junitReporter != nil {
|
||||
pr.junitReporter.BeforeSuiteDidRun(setupSummary)
|
||||
}
|
||||
}
|
||||
|
||||
// AfterSuiteDidRun implements ginkgo.Reporter.
|
||||
func (pr *prowReporter) AfterSuiteDidRun(setupSummary *types.SetupSummary) {
|
||||
if pr.junitReporter != nil {
|
||||
pr.junitReporter.AfterSuiteDidRun(setupSummary)
|
||||
}
|
||||
}
|
||||
|
||||
// SpecWillRun implements ginkgo.Reporter.
|
||||
func (pr *prowReporter) SpecWillRun(specSummary *types.SpecSummary) {
|
||||
if pr.junitReporter != nil {
|
||||
pr.junitReporter.SpecWillRun(specSummary)
|
||||
}
|
||||
}
|
||||
|
||||
// SpecDidComplete implements ginkgo.Reporter.
|
||||
func (pr *prowReporter) SpecDidComplete(specSummary *types.SpecSummary) {
|
||||
if pr.junitReporter != nil {
|
||||
pr.junitReporter.SpecDidComplete(specSummary)
|
||||
}
|
||||
}
|
||||
|
||||
// SpecSuiteDidEnd Prints a newline between "35 Passed | 0 Failed | 0 Pending | 0 Skipped" and "--- PASS:".
|
||||
func (pr *prowReporter) SpecSuiteDidEnd(summary *types.SuiteSummary) {
|
||||
if pr.junitReporter != nil {
|
||||
pr.junitReporter.SpecSuiteDidEnd(summary)
|
||||
}
|
||||
}
|
||||
17
vendor/sigs.k8s.io/controller-runtime/pkg/envtest/server.go
generated
vendored
17
vendor/sigs.k8s.io/controller-runtime/pkg/envtest/server.go
generated
vendored
@@ -37,15 +37,14 @@ var log = logf.RuntimeLog.WithName("test-env")
|
||||
|
||||
/*
|
||||
It's possible to override some defaults, by setting the following environment variables:
|
||||
USE_EXISTING_CLUSTER (boolean): if set to true, envtest will use an existing cluster
|
||||
TEST_ASSET_KUBE_APISERVER (string): path to the api-server binary to use
|
||||
TEST_ASSET_ETCD (string): path to the etcd binary to use
|
||||
TEST_ASSET_KUBECTL (string): path to the kubectl binary to use
|
||||
KUBEBUILDER_ASSETS (string): directory containing the binaries to use (api-server, etcd and kubectl). Defaults to /usr/local/kubebuilder/bin.
|
||||
KUBEBUILDER_CONTROLPLANE_START_TIMEOUT (string supported by time.ParseDuration): timeout for test control plane to start. Defaults to 20s.
|
||||
KUBEBUILDER_CONTROLPLANE_STOP_TIMEOUT (string supported by time.ParseDuration): timeout for test control plane to start. Defaults to 20s.
|
||||
KUBEBUILDER_ATTACH_CONTROL_PLANE_OUTPUT (boolean): if set to true, the control plane's stdout and stderr are attached to os.Stdout and os.Stderr
|
||||
|
||||
* USE_EXISTING_CLUSTER (boolean): if set to true, envtest will use an existing cluster
|
||||
* TEST_ASSET_KUBE_APISERVER (string): path to the api-server binary to use
|
||||
* TEST_ASSET_ETCD (string): path to the etcd binary to use
|
||||
* TEST_ASSET_KUBECTL (string): path to the kubectl binary to use
|
||||
* KUBEBUILDER_ASSETS (string): directory containing the binaries to use (api-server, etcd and kubectl). Defaults to /usr/local/kubebuilder/bin.
|
||||
* KUBEBUILDER_CONTROLPLANE_START_TIMEOUT (string supported by time.ParseDuration): timeout for test control plane to start. Defaults to 20s.
|
||||
* KUBEBUILDER_CONTROLPLANE_STOP_TIMEOUT (string supported by time.ParseDuration): timeout for test control plane to start. Defaults to 20s.
|
||||
* KUBEBUILDER_ATTACH_CONTROL_PLANE_OUTPUT (boolean): if set to true, the control plane's stdout and stderr are attached to os.Stdout and os.Stderr
|
||||
*/
|
||||
const (
|
||||
envUseExistingCluster = "USE_EXISTING_CLUSTER"
|
||||
|
||||
10
vendor/sigs.k8s.io/controller-runtime/pkg/envtest/webhook.go
generated
vendored
10
vendor/sigs.k8s.io/controller-runtime/pkg/envtest/webhook.go
generated
vendored
@@ -173,7 +173,7 @@ func WaitForWebhooks(config *rest.Config,
|
||||
mutatingWebhooks []*admissionv1.MutatingWebhookConfiguration,
|
||||
validatingWebhooks []*admissionv1.ValidatingWebhookConfiguration,
|
||||
options WebhookInstallOptions) error {
|
||||
waitingFor := map[schema.GroupVersionKind]*sets.String{}
|
||||
waitingFor := map[schema.GroupVersionKind]*sets.Set[string]{}
|
||||
|
||||
for _, hook := range mutatingWebhooks {
|
||||
h := hook
|
||||
@@ -183,7 +183,7 @@ func WaitForWebhooks(config *rest.Config,
|
||||
}
|
||||
|
||||
if _, ok := waitingFor[gvk]; !ok {
|
||||
waitingFor[gvk] = &sets.String{}
|
||||
waitingFor[gvk] = &sets.Set[string]{}
|
||||
}
|
||||
waitingFor[gvk].Insert(h.GetName())
|
||||
}
|
||||
@@ -196,7 +196,7 @@ func WaitForWebhooks(config *rest.Config,
|
||||
}
|
||||
|
||||
if _, ok := waitingFor[gvk]; !ok {
|
||||
waitingFor[gvk] = &sets.String{}
|
||||
waitingFor[gvk] = &sets.Set[string]{}
|
||||
}
|
||||
waitingFor[gvk].Insert(hook.GetName())
|
||||
}
|
||||
@@ -212,7 +212,7 @@ type webhookPoller struct {
|
||||
config *rest.Config
|
||||
|
||||
// waitingFor is the map of resources keyed by group version that have not yet been found in discovery
|
||||
waitingFor map[schema.GroupVersionKind]*sets.String
|
||||
waitingFor map[schema.GroupVersionKind]*sets.Set[string]
|
||||
}
|
||||
|
||||
// poll checks if all the resources have been found in discovery, and returns false if not.
|
||||
@@ -229,7 +229,7 @@ func (p *webhookPoller) poll() (done bool, err error) {
|
||||
delete(p.waitingFor, gvk)
|
||||
continue
|
||||
}
|
||||
for _, name := range names.List() {
|
||||
for _, name := range names.UnsortedList() {
|
||||
var obj = &unstructured.Unstructured{}
|
||||
obj.SetGroupVersionKind(gvk)
|
||||
err := c.Get(context.Background(), client.ObjectKey{
|
||||
|
||||
2
vendor/sigs.k8s.io/controller-runtime/pkg/handler/doc.go
generated
vendored
2
vendor/sigs.k8s.io/controller-runtime/pkg/handler/doc.go
generated
vendored
@@ -21,7 +21,7 @@ Controller.Watch in order to generate and enqueue reconcile.Request work items.
|
||||
|
||||
Generally, following premade event handlers should be sufficient for most use cases:
|
||||
|
||||
EventHandlers
|
||||
EventHandlers:
|
||||
|
||||
EnqueueRequestForObject - Enqueues a reconcile.Request containing the Name and Namespace of the object in the Event. This will
|
||||
cause the object that was the source of the Event (e.g. the created / deleted / updated object) to be
|
||||
|
||||
12
vendor/sigs.k8s.io/controller-runtime/pkg/healthz/healthz.go
generated
vendored
12
vendor/sigs.k8s.io/controller-runtime/pkg/healthz/healthz.go
generated
vendored
@@ -70,7 +70,7 @@ func (h *Handler) serveAggregated(resp http.ResponseWriter, req *http.Request) {
|
||||
parts = append(parts, checkStatus{name: "ping", healthy: true})
|
||||
}
|
||||
|
||||
for _, c := range excluded.List() {
|
||||
for _, c := range excluded.UnsortedList() {
|
||||
log.V(1).Info("cannot exclude health check, no matches for it", "checker", c)
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ func (h *Handler) serveAggregated(resp http.ResponseWriter, req *http.Request) {
|
||||
// any checks that the user requested to have excluded, but weren't actually
|
||||
// known checks. writeStatusAsText is always verbose on failure, and can be
|
||||
// forced to be verbose on success using the given argument.
|
||||
func writeStatusesAsText(resp http.ResponseWriter, parts []checkStatus, unknownExcludes sets.String, failed, forceVerbose bool) {
|
||||
func writeStatusesAsText(resp http.ResponseWriter, parts []checkStatus, unknownExcludes sets.Set[string], failed, forceVerbose bool) {
|
||||
resp.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||
resp.Header().Set("X-Content-Type-Options", "nosniff")
|
||||
|
||||
@@ -121,7 +121,7 @@ func writeStatusesAsText(resp http.ResponseWriter, parts []checkStatus, unknownE
|
||||
}
|
||||
|
||||
if unknownExcludes.Len() > 0 {
|
||||
fmt.Fprintf(resp, "warn: some health checks cannot be excluded: no matches for %s\n", formatQuoted(unknownExcludes.List()...))
|
||||
fmt.Fprintf(resp, "warn: some health checks cannot be excluded: no matches for %s\n", formatQuoted(unknownExcludes.UnsortedList()...))
|
||||
}
|
||||
|
||||
if failed {
|
||||
@@ -187,12 +187,12 @@ type Checker func(req *http.Request) error
|
||||
var Ping Checker = func(_ *http.Request) error { return nil }
|
||||
|
||||
// getExcludedChecks extracts the health check names to be excluded from the query param.
|
||||
func getExcludedChecks(r *http.Request) sets.String {
|
||||
func getExcludedChecks(r *http.Request) sets.Set[string] {
|
||||
checks, found := r.URL.Query()["exclude"]
|
||||
if found {
|
||||
return sets.NewString(checks...)
|
||||
return sets.New[string](checks...)
|
||||
}
|
||||
return sets.NewString()
|
||||
return sets.New[string]()
|
||||
}
|
||||
|
||||
// formatQuoted returns a formatted string of the health check names,
|
||||
|
||||
27
vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go
generated
vendored
27
vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go
generated
vendored
@@ -24,6 +24,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/uuid"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
@@ -91,7 +92,7 @@ type Controller struct {
|
||||
LogConstructor func(request *reconcile.Request) logr.Logger
|
||||
|
||||
// RecoverPanic indicates whether the panic caused by reconcile should be recovered.
|
||||
RecoverPanic bool
|
||||
RecoverPanic *bool
|
||||
}
|
||||
|
||||
// watchDescription contains all the information necessary to start a watch.
|
||||
@@ -105,7 +106,7 @@ type watchDescription struct {
|
||||
func (c *Controller) Reconcile(ctx context.Context, req reconcile.Request) (_ reconcile.Result, err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
if c.RecoverPanic {
|
||||
if c.RecoverPanic != nil && *c.RecoverPanic {
|
||||
for _, fn := range utilruntime.PanicHandlers {
|
||||
fn(r)
|
||||
}
|
||||
@@ -311,9 +312,11 @@ func (c *Controller) reconcileHandler(ctx context.Context, obj interface{}) {
|
||||
}
|
||||
|
||||
log := c.LogConstructor(&req)
|
||||
reconcileID := uuid.NewUUID()
|
||||
|
||||
log = log.WithValues("reconcileID", uuid.NewUUID())
|
||||
log = log.WithValues("reconcileID", reconcileID)
|
||||
ctx = logf.IntoContext(ctx, log)
|
||||
ctx = addReconcileID(ctx, reconcileID)
|
||||
|
||||
// RunInformersAndControllers the syncHandler, passing it the Namespace/Name string of the
|
||||
// resource to be synced.
|
||||
@@ -358,3 +361,21 @@ func (c *Controller) InjectFunc(f inject.Func) error {
|
||||
func (c *Controller) updateMetrics(reconcileTime time.Duration) {
|
||||
ctrlmetrics.ReconcileTime.WithLabelValues(c.Name).Observe(reconcileTime.Seconds())
|
||||
}
|
||||
|
||||
// ReconcileIDFromContext gets the reconcileID from the current context.
|
||||
func ReconcileIDFromContext(ctx context.Context) types.UID {
|
||||
r, ok := ctx.Value(reconcileIDKey{}).(types.UID)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// reconcileIDKey is a context.Context Value key. Its associated value should
|
||||
// be a types.UID.
|
||||
type reconcileIDKey struct{}
|
||||
|
||||
func addReconcileID(ctx context.Context, reconcileID types.UID) context.Context {
|
||||
return context.WithValue(ctx, reconcileIDKey{}, reconcileID)
|
||||
}
|
||||
|
||||
35
vendor/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils.go
generated
vendored
Normal file
35
vendor/sigs.k8s.io/controller-runtime/pkg/internal/field/selector/utils.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright 2022 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 selector
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/selection"
|
||||
)
|
||||
|
||||
// RequiresExactMatch checks if the given field selector is of the form `k=v` or `k==v`.
|
||||
func RequiresExactMatch(sel fields.Selector) (field, val string, required bool) {
|
||||
reqs := sel.Requirements()
|
||||
if len(reqs) != 1 {
|
||||
return "", "", false
|
||||
}
|
||||
req := reqs[0]
|
||||
if req.Operator != selection.Equals && req.Operator != selection.DoubleEquals {
|
||||
return "", "", false
|
||||
}
|
||||
return req.Field, req.Value, true
|
||||
}
|
||||
2
vendor/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder.go
generated
vendored
2
vendor/sigs.k8s.io/controller-runtime/pkg/internal/recorder/recorder.go
generated
vendored
@@ -100,7 +100,7 @@ func (p *Provider) getBroadcaster() record.EventBroadcaster {
|
||||
broadcaster.StartRecordingToSink(&corev1client.EventSinkImpl{Interface: p.evtClient})
|
||||
broadcaster.StartEventWatcher(
|
||||
func(e *corev1.Event) {
|
||||
p.logger.V(1).Info(e.Type, "object", e.InvolvedObject, "reason", e.Reason, "message", e.Message)
|
||||
p.logger.V(1).Info(e.Message, "type", e.Type, "object", e.InvolvedObject, "reason", e.Reason)
|
||||
})
|
||||
p.broadcaster = broadcaster
|
||||
p.stopBroadcaster = stop
|
||||
|
||||
10
vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/addr/manager.go
generated
vendored
10
vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/addr/manager.go
generated
vendored
@@ -71,10 +71,20 @@ func (c *portCache) add(port int) (bool, error) {
|
||||
}
|
||||
info, err := d.Info()
|
||||
if err != nil {
|
||||
// No-op if file no longer exists; may have been deleted by another
|
||||
// process/thread trying to allocate ports.
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
if time.Since(info.ModTime()) > portReserveTime {
|
||||
if err := os.Remove(filepath.Join(cacheDir, path)); err != nil {
|
||||
// No-op if file no longer exists; may have been deleted by another
|
||||
// process/thread trying to allocate ports.
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
24
vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/arguments.go
generated
vendored
24
vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/arguments.go
generated
vendored
@@ -93,12 +93,12 @@ type TemplateDefaults struct {
|
||||
// TemplateAndArguments joins structured arguments and non-structured arguments, preserving existing
|
||||
// behavior. Namely:
|
||||
//
|
||||
// 1. if templ has len > 0, it will be rendered against data
|
||||
// 2. the rendered template values that look like `--foo=bar` will be split
|
||||
// and appended to args, the rest will be kept around
|
||||
// 3. the given args will be rendered as string form. If a template is given,
|
||||
// no defaults will be used, otherwise defaults will be used
|
||||
// 4. a result of [args..., rest...] will be returned
|
||||
// 1. if templ has len > 0, it will be rendered against data
|
||||
// 2. the rendered template values that look like `--foo=bar` will be split
|
||||
// and appended to args, the rest will be kept around
|
||||
// 3. the given args will be rendered as string form. If a template is given,
|
||||
// no defaults will be used, otherwise defaults will be used
|
||||
// 4. a result of [args..., rest...] will be returned
|
||||
//
|
||||
// It returns the resulting rendered arguments, plus the arguments that were
|
||||
// not transferred to `args` during rendering.
|
||||
@@ -215,9 +215,9 @@ var (
|
||||
// for passing to exec.Command and friends, making use of the given defaults
|
||||
// as indicated for each particular argument.
|
||||
//
|
||||
// - Any flag in defaults that's not in Arguments will be present in the output
|
||||
// - Any flag that's present in Arguments will be passed the corresponding
|
||||
// defaults to do with as it will (ignore, append-to, suppress, etc).
|
||||
// - Any flag in defaults that's not in Arguments will be present in the output
|
||||
// - Any flag that's present in Arguments will be passed the corresponding
|
||||
// defaults to do with as it will (ignore, append-to, suppress, etc).
|
||||
func (a *Arguments) AsStrings(defaults map[string][]string) []string {
|
||||
// sort for deterministic ordering
|
||||
keysInOrder := make([]string, 0, len(defaults)+len(a.values))
|
||||
@@ -323,9 +323,9 @@ func (a *Arguments) SetRaw(key string, val Arg) *Arguments {
|
||||
// used in conjunction with SetRaw. For example, to set `--some-flag` to the
|
||||
// API server's CertDir, you could do:
|
||||
//
|
||||
// server.Configure().SetRaw("--some-flag", FuncArg(func(defaults []string) []string {
|
||||
// return []string{server.CertDir}
|
||||
// }))
|
||||
// server.Configure().SetRaw("--some-flag", FuncArg(func(defaults []string) []string {
|
||||
// return []string{server.CertDir}
|
||||
// }))
|
||||
//
|
||||
// FuncArg ignores Appends; if you need to support appending values too, consider implementing
|
||||
// Arg directly.
|
||||
|
||||
8
vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process.go
generated
vendored
8
vendor/sigs.k8s.io/controller-runtime/pkg/internal/testing/process/process.go
generated
vendored
@@ -184,16 +184,12 @@ func (ps *State) Start(stdout, stderr io.Writer) (err error) {
|
||||
ps.ready = true
|
||||
return nil
|
||||
case <-ps.waitDone:
|
||||
if pollerStopCh != nil {
|
||||
close(pollerStopCh)
|
||||
}
|
||||
close(pollerStopCh)
|
||||
return fmt.Errorf("timeout waiting for process %s to start successfully "+
|
||||
"(it may have failed to start, or stopped unexpectedly before becoming ready)",
|
||||
path.Base(ps.Path))
|
||||
case <-timedOut:
|
||||
if pollerStopCh != nil {
|
||||
close(pollerStopCh)
|
||||
}
|
||||
close(pollerStopCh)
|
||||
if ps.Cmd != nil {
|
||||
// intentionally ignore this -- we might've crashed, failed to start, etc
|
||||
ps.Cmd.Process.Signal(syscall.SIGTERM) //nolint:errcheck
|
||||
|
||||
15
vendor/sigs.k8s.io/controller-runtime/pkg/log/deleg.go
generated
vendored
15
vendor/sigs.k8s.io/controller-runtime/pkg/log/deleg.go
generated
vendored
@@ -73,6 +73,9 @@ func (p *loggerPromise) Fulfill(parentLogSink logr.LogSink) {
|
||||
|
||||
p.logger.lock.Lock()
|
||||
p.logger.logger = sink
|
||||
if withCallDepth, ok := sink.(logr.CallDepthLogSink); ok {
|
||||
p.logger.logger = withCallDepth.WithCallDepth(1)
|
||||
}
|
||||
p.logger.promise = nil
|
||||
p.logger.lock.Unlock()
|
||||
|
||||
@@ -141,7 +144,11 @@ func (l *DelegatingLogSink) WithName(name string) logr.LogSink {
|
||||
defer l.lock.RUnlock()
|
||||
|
||||
if l.promise == nil {
|
||||
return l.logger.WithName(name)
|
||||
sink := l.logger.WithName(name)
|
||||
if withCallDepth, ok := sink.(logr.CallDepthLogSink); ok {
|
||||
sink = withCallDepth.WithCallDepth(-1)
|
||||
}
|
||||
return sink
|
||||
}
|
||||
|
||||
res := &DelegatingLogSink{logger: l.logger}
|
||||
@@ -157,7 +164,11 @@ func (l *DelegatingLogSink) WithValues(tags ...interface{}) logr.LogSink {
|
||||
defer l.lock.RUnlock()
|
||||
|
||||
if l.promise == nil {
|
||||
return l.logger.WithValues(tags...)
|
||||
sink := l.logger.WithValues(tags...)
|
||||
if withCallDepth, ok := sink.(logr.CallDepthLogSink); ok {
|
||||
sink = withCallDepth.WithCallDepth(-1)
|
||||
}
|
||||
return sink
|
||||
}
|
||||
|
||||
res := &DelegatingLogSink{logger: l.logger}
|
||||
|
||||
4
vendor/sigs.k8s.io/controller-runtime/pkg/log/log.go
generated
vendored
4
vendor/sigs.k8s.io/controller-runtime/pkg/log/log.go
generated
vendored
@@ -17,7 +17,7 @@ limitations under the License.
|
||||
// Package log contains utilities for fetching a new logger
|
||||
// when one is not already available.
|
||||
//
|
||||
// The Log Handle
|
||||
// # The Log Handle
|
||||
//
|
||||
// This package contains a root logr.Logger Log. It may be used to
|
||||
// get a handle to whatever the root logging implementation is. By
|
||||
@@ -25,7 +25,7 @@ limitations under the License.
|
||||
// to loggers. When the implementation is set using SetLogger, these
|
||||
// "promises" will be converted over to real loggers.
|
||||
//
|
||||
// Logr
|
||||
// # Logr
|
||||
//
|
||||
// All logging in controller-runtime is structured, using a set of interfaces
|
||||
// defined by a package called logr
|
||||
|
||||
16
vendor/sigs.k8s.io/controller-runtime/pkg/manager/internal.go
generated
vendored
16
vendor/sigs.k8s.io/controller-runtime/pkg/manager/internal.go
generated
vendored
@@ -18,6 +18,7 @@ package manager
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
@@ -40,7 +41,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/cache"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/cluster"
|
||||
"sigs.k8s.io/controller-runtime/pkg/config/v1alpha1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/config/v1alpha1" //nolint:staticcheck
|
||||
"sigs.k8s.io/controller-runtime/pkg/healthz"
|
||||
"sigs.k8s.io/controller-runtime/pkg/internal/httpserver"
|
||||
intrec "sigs.k8s.io/controller-runtime/pkg/internal/recorder"
|
||||
@@ -107,7 +108,7 @@ type controllerManager struct {
|
||||
healthzHandler *healthz.Handler
|
||||
|
||||
// controllerOptions are the global controller options.
|
||||
controllerOptions v1alpha1.ControllerConfigurationSpec
|
||||
controllerOptions v1alpha1.ControllerConfigurationSpec //nolint:staticcheck
|
||||
|
||||
// Logger is the logger that should be used by this manager.
|
||||
// If none is set, it defaults to log.Log global logger.
|
||||
@@ -135,12 +136,17 @@ type controllerManager struct {
|
||||
// if not set, webhook server would look up the server key and certificate in
|
||||
// {TempDir}/k8s-webhook-server/serving-certs
|
||||
certDir string
|
||||
// tlsOpts is used to allow configuring the TLS config used for the webhook server.
|
||||
tlsOpts []func(*tls.Config)
|
||||
|
||||
webhookServer *webhook.Server
|
||||
// webhookServerOnce will be called in GetWebhookServer() to optionally initialize
|
||||
// webhookServer if unset, and Add() it to controllerManager.
|
||||
webhookServerOnce sync.Once
|
||||
|
||||
// leaderElectionID is the name of the resource that leader election
|
||||
// will use for holding the leader lock.
|
||||
leaderElectionID string
|
||||
// leaseDuration is the duration that non-leader candidates will
|
||||
// wait to force acquire leadership.
|
||||
leaseDuration time.Duration
|
||||
@@ -305,6 +311,7 @@ func (cm *controllerManager) GetWebhookServer() *webhook.Server {
|
||||
Port: cm.port,
|
||||
Host: cm.host,
|
||||
CertDir: cm.certDir,
|
||||
TLSOpts: cm.tlsOpts,
|
||||
}
|
||||
}
|
||||
if err := cm.Add(cm.webhookServer); err != nil {
|
||||
@@ -318,7 +325,7 @@ func (cm *controllerManager) GetLogger() logr.Logger {
|
||||
return cm.logger
|
||||
}
|
||||
|
||||
func (cm *controllerManager) GetControllerOptions() v1alpha1.ControllerConfigurationSpec {
|
||||
func (cm *controllerManager) GetControllerOptions() v1alpha1.ControllerConfigurationSpec { //nolint:staticcheck
|
||||
return cm.controllerOptions
|
||||
}
|
||||
|
||||
@@ -402,6 +409,8 @@ func (cm *controllerManager) Start(ctx context.Context) (err error) {
|
||||
cm.Unlock()
|
||||
return errors.New("manager already started")
|
||||
}
|
||||
cm.started = true
|
||||
|
||||
var ready bool
|
||||
defer func() {
|
||||
// Only unlock the manager if we haven't reached
|
||||
@@ -633,6 +642,7 @@ func (cm *controllerManager) startLeaderElection(ctx context.Context) (err error
|
||||
},
|
||||
},
|
||||
ReleaseOnCancel: cm.leaderElectionReleaseOnCancel,
|
||||
Name: cm.leaderElectionID,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
94
vendor/sigs.k8s.io/controller-runtime/pkg/manager/manager.go
generated
vendored
94
vendor/sigs.k8s.io/controller-runtime/pkg/manager/manager.go
generated
vendored
@@ -18,6 +18,7 @@ package manager
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -35,8 +36,8 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/cache"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/cluster"
|
||||
"sigs.k8s.io/controller-runtime/pkg/config"
|
||||
"sigs.k8s.io/controller-runtime/pkg/config/v1alpha1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/config" //nolint:staticcheck
|
||||
"sigs.k8s.io/controller-runtime/pkg/config/v1alpha1" //nolint:staticcheck
|
||||
"sigs.k8s.io/controller-runtime/pkg/healthz"
|
||||
intrec "sigs.k8s.io/controller-runtime/pkg/internal/recorder"
|
||||
"sigs.k8s.io/controller-runtime/pkg/leaderelection"
|
||||
@@ -93,7 +94,11 @@ type Manager interface {
|
||||
GetLogger() logr.Logger
|
||||
|
||||
// GetControllerOptions returns controller global configuration options.
|
||||
GetControllerOptions() v1alpha1.ControllerConfigurationSpec
|
||||
//
|
||||
// Deprecated: In a future version, the returned value is going to be replaced with a
|
||||
// different type that doesn't rely on component configuration types.
|
||||
// This is a temporary warning, and no action is needed as of today.
|
||||
GetControllerOptions() v1alpha1.ControllerConfigurationSpec //nolint:staticcheck
|
||||
}
|
||||
|
||||
// Options are the arguments for creating a new Manager.
|
||||
@@ -142,18 +147,36 @@ type Options struct {
|
||||
LeaderElection bool
|
||||
|
||||
// LeaderElectionResourceLock determines which resource lock to use for leader election,
|
||||
// defaults to "configmapsleases". Change this value only if you know what you are doing.
|
||||
// Otherwise, users of your controller might end up with multiple running instances that
|
||||
// defaults to "leases". Change this value only if you know what you are doing.
|
||||
//
|
||||
// If you are using `configmaps`/`endpoints` resource lock and want to migrate to "leases",
|
||||
// you might do so by migrating to the respective multilock first ("configmapsleases" or "endpointsleases"),
|
||||
// which will acquire a leader lock on both resources.
|
||||
// After all your users have migrated to the multilock, you can go ahead and migrate to "leases".
|
||||
// Please also keep in mind, that users might skip versions of your controller.
|
||||
//
|
||||
// Note: before controller-runtime version v0.7, it was set to "configmaps".
|
||||
// And from v0.7 to v0.11, the default was "configmapsleases", which was
|
||||
// used to migrate from configmaps to leases.
|
||||
// Since the default was "configmapsleases" for over a year, spanning five minor releases,
|
||||
// any actively maintained operators are very likely to have a released version that uses
|
||||
// "configmapsleases". Therefore defaulting to "leases" should be safe since v0.12.
|
||||
//
|
||||
// So, what do you have to do when you are updating your controller-runtime dependency
|
||||
// from a lower version to v0.12 or newer?
|
||||
// - If your operator matches at least one of these conditions:
|
||||
// - the LeaderElectionResourceLock in your operator has already been explicitly set to "leases"
|
||||
// - the old controller-runtime version is between v0.7.0 and v0.11.x and the
|
||||
// LeaderElectionResourceLock wasn't set or was set to "leases"/"configmapsleases"/"endpointsleases"
|
||||
// feel free to update controller-runtime to v0.12 or newer.
|
||||
// - Otherwise, you may have to take these steps:
|
||||
// 1. update controller-runtime to v0.12 or newer in your go.mod
|
||||
// 2. set LeaderElectionResourceLock to "configmapsleases" (or "endpointsleases")
|
||||
// 3. package your operator and upgrade it in all your clusters
|
||||
// 4. only if you have finished 3, you can remove the LeaderElectionResourceLock to use the default "leases"
|
||||
// Otherwise, your operator might end up with multiple running instances that
|
||||
// each acquired leadership through different resource locks during upgrades and thus
|
||||
// act on the same resources concurrently.
|
||||
// If you want to migrate to the "leases" resource lock, you might do so by migrating to the
|
||||
// respective multilock first ("configmapsleases" or "endpointsleases"), which will acquire a
|
||||
// leader lock on both resources. After all your users have migrated to the multilock, you can
|
||||
// go ahead and migrate to "leases". Please also keep in mind, that users might skip versions
|
||||
// of your controller.
|
||||
//
|
||||
// Note: before controller-runtime version v0.7, the resource lock was set to "configmaps".
|
||||
// Please keep this in mind, when planning a proper migration path for your controller.
|
||||
LeaderElectionResourceLock string
|
||||
|
||||
// LeaderElectionNamespace determines the namespace in which the leader
|
||||
@@ -175,6 +198,12 @@ type Options struct {
|
||||
// LeaseDuration time first.
|
||||
LeaderElectionReleaseOnCancel bool
|
||||
|
||||
// LeaderElectionResourceLockInterface allows to provide a custom resourcelock.Interface that was created outside
|
||||
// of the controller-runtime. If this value is set the options LeaderElectionID, LeaderElectionNamespace,
|
||||
// LeaderElectionResourceLock, LeaseDuration, RenewDeadline and RetryPeriod will be ignored. This can be useful if you
|
||||
// want to use a locking mechanism that is currently not supported, like a MultiLock across two Kubernetes clusters.
|
||||
LeaderElectionResourceLockInterface resourcelock.Interface
|
||||
|
||||
// LeaseDuration is the duration that non-leader candidates will
|
||||
// wait to force acquire leadership. This is measured against time of
|
||||
// last observed ack. Default is 15 seconds.
|
||||
@@ -201,6 +230,7 @@ type Options struct {
|
||||
|
||||
// HealthProbeBindAddress is the TCP address that the controller should bind to
|
||||
// for serving health probes
|
||||
// It can be set to "0" or "" to disable serving the health probe.
|
||||
HealthProbeBindAddress string
|
||||
|
||||
// Readiness probe endpoint name, defaults to "readyz"
|
||||
@@ -223,6 +253,9 @@ type Options struct {
|
||||
// It is used to set webhook.Server.CertDir if WebhookServer is not set.
|
||||
CertDir string
|
||||
|
||||
// TLSOpts is used to allow configuring the TLS config used for the webhook server.
|
||||
TLSOpts []func(*tls.Config)
|
||||
|
||||
// WebhookServer is an externally configured webhook.Server. By default,
|
||||
// a Manager will create a default server using Port, Host, and CertDir;
|
||||
// if this is set, the Manager will use this server instead.
|
||||
@@ -268,7 +301,11 @@ type Options struct {
|
||||
// Controller contains global configuration options for controllers
|
||||
// registered within this manager.
|
||||
// +optional
|
||||
Controller v1alpha1.ControllerConfigurationSpec
|
||||
//
|
||||
// Deprecated: In a future version, the type of this field is going to be replaced with a
|
||||
// different struct that doesn't rely on component configuration types.
|
||||
// This is a temporary warning, and no action is needed as of today.
|
||||
Controller v1alpha1.ControllerConfigurationSpec //nolint:staticcheck
|
||||
|
||||
// makeBroadcaster allows deferring the creation of the broadcaster to
|
||||
// avoid leaking goroutines if we never call Start on this manager. It also
|
||||
@@ -358,14 +395,19 @@ func New(config *rest.Config, options Options) (Manager, error) {
|
||||
}
|
||||
}
|
||||
|
||||
resourceLock, err := options.newResourceLock(leaderConfig, leaderRecorderProvider, leaderelection.Options{
|
||||
LeaderElection: options.LeaderElection,
|
||||
LeaderElectionResourceLock: options.LeaderElectionResourceLock,
|
||||
LeaderElectionID: options.LeaderElectionID,
|
||||
LeaderElectionNamespace: options.LeaderElectionNamespace,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
var resourceLock resourcelock.Interface
|
||||
if options.LeaderElectionResourceLockInterface != nil && options.LeaderElection {
|
||||
resourceLock = options.LeaderElectionResourceLockInterface
|
||||
} else {
|
||||
resourceLock, err = options.newResourceLock(leaderConfig, leaderRecorderProvider, leaderelection.Options{
|
||||
LeaderElection: options.LeaderElection,
|
||||
LeaderElectionResourceLock: options.LeaderElectionResourceLock,
|
||||
LeaderElectionID: options.LeaderElectionID,
|
||||
LeaderElectionNamespace: options.LeaderElectionNamespace,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Create the metrics listener. This will throw an error if the metrics bind
|
||||
@@ -403,7 +445,9 @@ func New(config *rest.Config, options Options) (Manager, error) {
|
||||
port: options.Port,
|
||||
host: options.Host,
|
||||
certDir: options.CertDir,
|
||||
tlsOpts: options.TLSOpts,
|
||||
webhookServer: options.WebhookServer,
|
||||
leaderElectionID: options.LeaderElectionID,
|
||||
leaseDuration: *options.LeaseDuration,
|
||||
renewDeadline: *options.RenewDeadline,
|
||||
retryPeriod: *options.RetryPeriod,
|
||||
@@ -420,6 +464,8 @@ func New(config *rest.Config, options Options) (Manager, error) {
|
||||
// AndFrom will use a supplied type and convert to Options
|
||||
// any options already set on Options will be ignored, this is used to allow
|
||||
// cli flags to override anything specified in the config file.
|
||||
//
|
||||
// Deprecated: This method will be removed in a future release.
|
||||
func (o Options) AndFrom(loader config.ControllerManagerConfiguration) (Options, error) {
|
||||
if inj, wantsScheme := loader.(inject.Scheme); wantsScheme {
|
||||
err := inj.InjectScheme(o.Scheme)
|
||||
@@ -485,6 +531,8 @@ func (o Options) AndFrom(loader config.ControllerManagerConfiguration) (Options,
|
||||
}
|
||||
|
||||
// AndFromOrDie will use options.AndFrom() and will panic if there are errors.
|
||||
//
|
||||
// Deprecated: This method will be removed in a future release.
|
||||
func (o Options) AndFromOrDie(loader config.ControllerManagerConfiguration) Options {
|
||||
o, err := o.AndFrom(loader)
|
||||
if err != nil {
|
||||
@@ -493,7 +541,7 @@ func (o Options) AndFromOrDie(loader config.ControllerManagerConfiguration) Opti
|
||||
return o
|
||||
}
|
||||
|
||||
func (o Options) setLeaderElectionConfig(obj v1alpha1.ControllerManagerConfigurationSpec) Options {
|
||||
func (o Options) setLeaderElectionConfig(obj v1alpha1.ControllerManagerConfigurationSpec) Options { //nolint:staticcheck
|
||||
if obj.LeaderElection == nil {
|
||||
// The source does not have any configuration; noop
|
||||
return o
|
||||
|
||||
120
vendor/sigs.k8s.io/controller-runtime/pkg/metrics/client_go_adapter.go
generated
vendored
120
vendor/sigs.k8s.io/controller-runtime/pkg/metrics/client_go_adapter.go
generated
vendored
@@ -22,7 +22,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
reflectormetrics "k8s.io/client-go/tools/cache"
|
||||
clientmetrics "k8s.io/client-go/tools/metrics"
|
||||
)
|
||||
|
||||
@@ -37,19 +36,6 @@ const (
|
||||
ResultKey = "requests_total"
|
||||
)
|
||||
|
||||
// Metrics subsystem and all keys used by the reflectors.
|
||||
const (
|
||||
ReflectorSubsystem = "reflector"
|
||||
ListsTotalKey = "lists_total"
|
||||
ListsDurationKey = "list_duration_seconds"
|
||||
ItemsPerListKey = "items_per_list"
|
||||
WatchesTotalKey = "watches_total"
|
||||
ShortWatchesTotalKey = "short_watches_total"
|
||||
WatchDurationKey = "watch_duration_seconds"
|
||||
ItemsPerWatchKey = "items_per_watch"
|
||||
LastResourceVersionKey = "last_resource_version"
|
||||
)
|
||||
|
||||
var (
|
||||
// client metrics.
|
||||
|
||||
@@ -81,64 +67,10 @@ var (
|
||||
Name: ResultKey,
|
||||
Help: "Number of HTTP requests, partitioned by status code, method, and host.",
|
||||
}, []string{"code", "method", "host"})
|
||||
|
||||
// reflector metrics.
|
||||
|
||||
// TODO(directxman12): update these to be histograms once the metrics overhaul KEP
|
||||
// PRs start landing.
|
||||
|
||||
listsTotal = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||
Subsystem: ReflectorSubsystem,
|
||||
Name: ListsTotalKey,
|
||||
Help: "Total number of API lists done by the reflectors",
|
||||
}, []string{"name"})
|
||||
|
||||
listsDuration = prometheus.NewSummaryVec(prometheus.SummaryOpts{
|
||||
Subsystem: ReflectorSubsystem,
|
||||
Name: ListsDurationKey,
|
||||
Help: "How long an API list takes to return and decode for the reflectors",
|
||||
}, []string{"name"})
|
||||
|
||||
itemsPerList = prometheus.NewSummaryVec(prometheus.SummaryOpts{
|
||||
Subsystem: ReflectorSubsystem,
|
||||
Name: ItemsPerListKey,
|
||||
Help: "How many items an API list returns to the reflectors",
|
||||
}, []string{"name"})
|
||||
|
||||
watchesTotal = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||
Subsystem: ReflectorSubsystem,
|
||||
Name: WatchesTotalKey,
|
||||
Help: "Total number of API watches done by the reflectors",
|
||||
}, []string{"name"})
|
||||
|
||||
shortWatchesTotal = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||
Subsystem: ReflectorSubsystem,
|
||||
Name: ShortWatchesTotalKey,
|
||||
Help: "Total number of short API watches done by the reflectors",
|
||||
}, []string{"name"})
|
||||
|
||||
watchDuration = prometheus.NewSummaryVec(prometheus.SummaryOpts{
|
||||
Subsystem: ReflectorSubsystem,
|
||||
Name: WatchDurationKey,
|
||||
Help: "How long an API watch takes to return and decode for the reflectors",
|
||||
}, []string{"name"})
|
||||
|
||||
itemsPerWatch = prometheus.NewSummaryVec(prometheus.SummaryOpts{
|
||||
Subsystem: ReflectorSubsystem,
|
||||
Name: ItemsPerWatchKey,
|
||||
Help: "How many items an API watch returns to the reflectors",
|
||||
}, []string{"name"})
|
||||
|
||||
lastResourceVersion = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Subsystem: ReflectorSubsystem,
|
||||
Name: LastResourceVersionKey,
|
||||
Help: "Last resource version seen for the reflectors",
|
||||
}, []string{"name"})
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerClientMetrics()
|
||||
registerReflectorMetrics()
|
||||
}
|
||||
|
||||
// registerClientMetrics sets up the client latency metrics from client-go.
|
||||
@@ -152,20 +84,6 @@ func registerClientMetrics() {
|
||||
})
|
||||
}
|
||||
|
||||
// registerReflectorMetrics sets up reflector (reconcile) loop metrics.
|
||||
func registerReflectorMetrics() {
|
||||
Registry.MustRegister(listsTotal)
|
||||
Registry.MustRegister(listsDuration)
|
||||
Registry.MustRegister(itemsPerList)
|
||||
Registry.MustRegister(watchesTotal)
|
||||
Registry.MustRegister(shortWatchesTotal)
|
||||
Registry.MustRegister(watchDuration)
|
||||
Registry.MustRegister(itemsPerWatch)
|
||||
Registry.MustRegister(lastResourceVersion)
|
||||
|
||||
reflectormetrics.SetReflectorMetricsProvider(reflectorMetricsProvider{})
|
||||
}
|
||||
|
||||
// this section contains adapters, implementations, and other sundry organic, artisanally
|
||||
// hand-crafted syntax trees required to convince client-go that it actually wants to let
|
||||
// someone use its metrics.
|
||||
@@ -191,41 +109,3 @@ type resultAdapter struct {
|
||||
func (r *resultAdapter) Increment(_ context.Context, code, method, host string) {
|
||||
r.metric.WithLabelValues(code, method, host).Inc()
|
||||
}
|
||||
|
||||
// Reflector metrics provider (method #2 for client-go metrics),
|
||||
// copied (more-or-less directly) from k8s.io/kubernetes setup code
|
||||
// (which isn't anywhere in an easily-importable place).
|
||||
|
||||
type reflectorMetricsProvider struct{}
|
||||
|
||||
func (reflectorMetricsProvider) NewListsMetric(name string) reflectormetrics.CounterMetric {
|
||||
return listsTotal.WithLabelValues(name)
|
||||
}
|
||||
|
||||
func (reflectorMetricsProvider) NewListDurationMetric(name string) reflectormetrics.SummaryMetric {
|
||||
return listsDuration.WithLabelValues(name)
|
||||
}
|
||||
|
||||
func (reflectorMetricsProvider) NewItemsInListMetric(name string) reflectormetrics.SummaryMetric {
|
||||
return itemsPerList.WithLabelValues(name)
|
||||
}
|
||||
|
||||
func (reflectorMetricsProvider) NewWatchesMetric(name string) reflectormetrics.CounterMetric {
|
||||
return watchesTotal.WithLabelValues(name)
|
||||
}
|
||||
|
||||
func (reflectorMetricsProvider) NewShortWatchesMetric(name string) reflectormetrics.CounterMetric {
|
||||
return shortWatchesTotal.WithLabelValues(name)
|
||||
}
|
||||
|
||||
func (reflectorMetricsProvider) NewWatchDurationMetric(name string) reflectormetrics.SummaryMetric {
|
||||
return watchDuration.WithLabelValues(name)
|
||||
}
|
||||
|
||||
func (reflectorMetricsProvider) NewItemsInWatchMetric(name string) reflectormetrics.SummaryMetric {
|
||||
return itemsPerWatch.WithLabelValues(name)
|
||||
}
|
||||
|
||||
func (reflectorMetricsProvider) NewLastResourceVersionMetric(name string) reflectormetrics.GaugeMetric {
|
||||
return lastResourceVersion.WithLabelValues(name)
|
||||
}
|
||||
|
||||
40
vendor/sigs.k8s.io/controller-runtime/pkg/metrics/leaderelection.go
generated
vendored
Normal file
40
vendor/sigs.k8s.io/controller-runtime/pkg/metrics/leaderelection.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"k8s.io/client-go/tools/leaderelection"
|
||||
)
|
||||
|
||||
// This file is copied and adapted from k8s.io/component-base/metrics/prometheus/clientgo/leaderelection
|
||||
// which registers metrics to the k8s legacy Registry. We require very
|
||||
// similar functionality, but must register metrics to a different Registry.
|
||||
|
||||
var (
|
||||
leaderGauge = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "leader_election_master_status",
|
||||
Help: "Gauge of if the reporting system is master of the relevant lease, 0 indicates backup, 1 indicates master. 'name' is the string used to identify the lease. Please make sure to group by name.",
|
||||
}, []string{"name"})
|
||||
)
|
||||
|
||||
func init() {
|
||||
Registry.MustRegister(leaderGauge)
|
||||
leaderelection.SetProvider(leaderelectionMetricsProvider{})
|
||||
}
|
||||
|
||||
type leaderelectionMetricsProvider struct{}
|
||||
|
||||
func (leaderelectionMetricsProvider) NewLeaderMetric() leaderelection.SwitchMetric {
|
||||
return &switchAdapter{gauge: leaderGauge}
|
||||
}
|
||||
|
||||
type switchAdapter struct {
|
||||
gauge *prometheus.GaugeVec
|
||||
}
|
||||
|
||||
func (s *switchAdapter) On(name string) {
|
||||
s.gauge.WithLabelValues(name).Set(1.0)
|
||||
}
|
||||
|
||||
func (s *switchAdapter) Off(name string) {
|
||||
s.gauge.WithLabelValues(name).Set(0.0)
|
||||
}
|
||||
4
vendor/sigs.k8s.io/controller-runtime/pkg/metrics/workqueue.go
generated
vendored
4
vendor/sigs.k8s.io/controller-runtime/pkg/metrics/workqueue.go
generated
vendored
@@ -21,8 +21,8 @@ import (
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
)
|
||||
|
||||
// This file is copied and adapted from k8s.io/kubernetes/pkg/util/workqueue/prometheus
|
||||
// which registers metrics to the default prometheus Registry. We require very
|
||||
// This file is copied and adapted from k8s.io/component-base/metrics/prometheus/workqueue
|
||||
// which registers metrics to the k8s legacy Registry. We require very
|
||||
// similar functionality, but must register metrics to a different Registry.
|
||||
|
||||
// Metrics subsystem and all keys used by the workqueue.
|
||||
|
||||
41
vendor/sigs.k8s.io/controller-runtime/pkg/predicate/predicate.go
generated
vendored
41
vendor/sigs.k8s.io/controller-runtime/pkg/predicate/predicate.go
generated
vendored
@@ -50,6 +50,7 @@ var _ Predicate = GenerationChangedPredicate{}
|
||||
var _ Predicate = AnnotationChangedPredicate{}
|
||||
var _ Predicate = or{}
|
||||
var _ Predicate = and{}
|
||||
var _ Predicate = not{}
|
||||
|
||||
// Funcs is a function that implements Predicate.
|
||||
type Funcs struct {
|
||||
@@ -176,9 +177,9 @@ func (GenerationChangedPredicate) Update(e event.UpdateEvent) bool {
|
||||
// This predicate will skip update events that have no change in the object's annotation.
|
||||
// It is intended to be used in conjunction with the GenerationChangedPredicate, as in the following example:
|
||||
//
|
||||
// Controller.Watch(
|
||||
// Controller.Watch(
|
||||
// &source.Kind{Type: v1.MyCustomKind},
|
||||
// &handler.EnqueueRequestForObject{},
|
||||
// &handler.EnqueueRequestForObject{},
|
||||
// predicate.Or(predicate.GenerationChangedPredicate{}, predicate.AnnotationChangedPredicate{}))
|
||||
//
|
||||
// This is mostly useful for controllers that needs to trigger both when the resource's generation is incremented
|
||||
@@ -207,9 +208,10 @@ func (AnnotationChangedPredicate) Update(e event.UpdateEvent) bool {
|
||||
// It is intended to be used in conjunction with the GenerationChangedPredicate, as in the following example:
|
||||
//
|
||||
// Controller.Watch(
|
||||
// &source.Kind{Type: v1.MyCustomKind},
|
||||
// &handler.EnqueueRequestForObject{},
|
||||
// predicate.Or(predicate.GenerationChangedPredicate{}, predicate.LabelChangedPredicate{}))
|
||||
//
|
||||
// &source.Kind{Type: v1.MyCustomKind},
|
||||
// &handler.EnqueueRequestForObject{},
|
||||
// predicate.Or(predicate.GenerationChangedPredicate{}, predicate.LabelChangedPredicate{}))
|
||||
//
|
||||
// This will be helpful when object's labels is carrying some extra specification information beyond object's spec,
|
||||
// and the controller will be triggered if any valid spec change (not only in spec, but also in labels) happens.
|
||||
@@ -339,6 +341,35 @@ func (o or) Generic(e event.GenericEvent) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Not returns a predicate that implements a logical NOT of the predicate passed to it.
|
||||
func Not(predicate Predicate) Predicate {
|
||||
return not{predicate}
|
||||
}
|
||||
|
||||
type not struct {
|
||||
predicate Predicate
|
||||
}
|
||||
|
||||
func (n not) InjectFunc(f inject.Func) error {
|
||||
return f(n.predicate)
|
||||
}
|
||||
|
||||
func (n not) Create(e event.CreateEvent) bool {
|
||||
return !n.predicate.Create(e)
|
||||
}
|
||||
|
||||
func (n not) Update(e event.UpdateEvent) bool {
|
||||
return !n.predicate.Update(e)
|
||||
}
|
||||
|
||||
func (n not) Delete(e event.DeleteEvent) bool {
|
||||
return !n.predicate.Delete(e)
|
||||
}
|
||||
|
||||
func (n not) Generic(e event.GenericEvent) bool {
|
||||
return !n.predicate.Generic(e)
|
||||
}
|
||||
|
||||
// LabelSelectorPredicate constructs a Predicate from a LabelSelector.
|
||||
// Only objects matching the LabelSelector will be admitted.
|
||||
func LabelSelectorPredicate(s metav1.LabelSelector) (Predicate, error) {
|
||||
|
||||
16
vendor/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile.go
generated
vendored
16
vendor/sigs.k8s.io/controller-runtime/pkg/reconcile/reconcile.go
generated
vendored
@@ -61,24 +61,24 @@ Deleting Kubernetes objects) or external Events (GitHub Webhooks, polling extern
|
||||
|
||||
Example reconcile Logic:
|
||||
|
||||
* Read an object and all the Pods it owns.
|
||||
* Observe that the object spec specifies 5 replicas but actual cluster contains only 1 Pod replica.
|
||||
* Create 4 Pods and set their OwnerReferences to the object.
|
||||
* Read an object and all the Pods it owns.
|
||||
* Observe that the object spec specifies 5 replicas but actual cluster contains only 1 Pod replica.
|
||||
* Create 4 Pods and set their OwnerReferences to the object.
|
||||
|
||||
reconcile may be implemented as either a type:
|
||||
|
||||
type reconcile struct {}
|
||||
type reconciler struct {}
|
||||
|
||||
func (reconcile) reconcile(controller.Request) (controller.Result, error) {
|
||||
func (reconciler) Reconcile(ctx context.Context, o reconcile.Request) (reconcile.Result, error) {
|
||||
// Implement business logic of reading and writing objects here
|
||||
return controller.Result{}, nil
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
|
||||
Or as a function:
|
||||
|
||||
controller.Func(func(o controller.Request) (controller.Result, error) {
|
||||
reconcile.Func(func(ctx context.Context, o reconcile.Request) (reconcile.Result, error) {
|
||||
// Implement business logic of reading and writing objects here
|
||||
return controller.Result{}, nil
|
||||
return reconcile.Result{}, nil
|
||||
})
|
||||
|
||||
Reconciliation is level-based, meaning action isn't driven off changes in individual Events, but instead is
|
||||
|
||||
45
vendor/sigs.k8s.io/controller-runtime/pkg/scheme/scheme.go
generated
vendored
45
vendor/sigs.k8s.io/controller-runtime/pkg/scheme/scheme.go
generated
vendored
@@ -21,37 +21,36 @@ limitations under the License.
|
||||
// Each API group should define a utility function
|
||||
// called AddToScheme for adding its types to a Scheme:
|
||||
//
|
||||
// // in package myapigroupv1...
|
||||
// var (
|
||||
// SchemeGroupVersion = schema.GroupVersion{Group: "my.api.group", Version: "v1"}
|
||||
// SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion}
|
||||
// AddToScheme = SchemeBuilder.AddToScheme
|
||||
// )
|
||||
// // in package myapigroupv1...
|
||||
// var (
|
||||
// SchemeGroupVersion = schema.GroupVersion{Group: "my.api.group", Version: "v1"}
|
||||
// SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion}
|
||||
// AddToScheme = SchemeBuilder.AddToScheme
|
||||
// )
|
||||
//
|
||||
// func init() {
|
||||
// SchemeBuilder.Register(&MyType{}, &MyTypeList)
|
||||
// }
|
||||
// var (
|
||||
// scheme *runtime.Scheme = runtime.NewScheme()
|
||||
// )
|
||||
// func init() {
|
||||
// SchemeBuilder.Register(&MyType{}, &MyTypeList)
|
||||
// }
|
||||
// var (
|
||||
// scheme *runtime.Scheme = runtime.NewScheme()
|
||||
// )
|
||||
//
|
||||
// This also true of the built-in Kubernetes types. Then, in the entrypoint for
|
||||
// your manager, assemble the scheme containing exactly the types you need,
|
||||
// panicing if scheme registration failed. For instance, if our controller needs
|
||||
// types from the core/v1 API group (e.g. Pod), plus types from my.api.group/v1:
|
||||
//
|
||||
// func init() {
|
||||
// utilruntime.Must(myapigroupv1.AddToScheme(scheme))
|
||||
// utilruntime.Must(kubernetesscheme.AddToScheme(scheme))
|
||||
// }
|
||||
//
|
||||
// func main() {
|
||||
// mgr := controllers.NewManager(context.Background(), controllers.GetConfigOrDie(), manager.Options{
|
||||
// Scheme: scheme,
|
||||
// })
|
||||
// // ...
|
||||
// }
|
||||
// func init() {
|
||||
// utilruntime.Must(myapigroupv1.AddToScheme(scheme))
|
||||
// utilruntime.Must(kubernetesscheme.AddToScheme(scheme))
|
||||
// }
|
||||
//
|
||||
// func main() {
|
||||
// mgr := controllers.NewManager(context.Background(), controllers.GetConfigOrDie(), manager.Options{
|
||||
// Scheme: scheme,
|
||||
// })
|
||||
// // ...
|
||||
// }
|
||||
package scheme
|
||||
|
||||
import (
|
||||
|
||||
15
vendor/sigs.k8s.io/controller-runtime/pkg/source/source.go
generated
vendored
15
vendor/sigs.k8s.io/controller-runtime/pkg/source/source.go
generated
vendored
@@ -83,6 +83,10 @@ func (ks *kindWithCache) Start(ctx context.Context, handler handler.EventHandler
|
||||
return ks.kind.Start(ctx, handler, queue, prct...)
|
||||
}
|
||||
|
||||
func (ks *kindWithCache) String() string {
|
||||
return ks.kind.String()
|
||||
}
|
||||
|
||||
func (ks *kindWithCache) WaitForSync(ctx context.Context) error {
|
||||
return ks.kind.WaitForSync(ctx)
|
||||
}
|
||||
@@ -155,7 +159,11 @@ func (ks *Kind) Start(ctx context.Context, handler handler.EventHandler, queue w
|
||||
return
|
||||
}
|
||||
|
||||
i.AddEventHandler(internal.EventHandler{Queue: queue, EventHandler: handler, Predicates: prct})
|
||||
_, err := i.AddEventHandler(internal.EventHandler{Queue: queue, EventHandler: handler, Predicates: prct})
|
||||
if err != nil {
|
||||
ks.started <- err
|
||||
return
|
||||
}
|
||||
if !ks.cache.WaitForCacheSync(ctx) {
|
||||
// Would be great to return something more informative here
|
||||
ks.started <- errors.New("cache did not sync")
|
||||
@@ -351,7 +359,10 @@ func (is *Informer) Start(ctx context.Context, handler handler.EventHandler, que
|
||||
return fmt.Errorf("must specify Informer.Informer")
|
||||
}
|
||||
|
||||
is.Informer.AddEventHandler(internal.EventHandler{Queue: queue, EventHandler: handler, Predicates: prct})
|
||||
_, err := is.Informer.AddEventHandler(internal.EventHandler{Queue: queue, EventHandler: handler, Predicates: prct})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
13
vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter.go
generated
vendored
13
vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter.go
generated
vendored
@@ -21,6 +21,8 @@ import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
admissionv1 "k8s.io/api/admission/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
@@ -56,6 +58,17 @@ func (h *mutatingHandler) Handle(ctx context.Context, req Request) Response {
|
||||
panic("defaulter should never be nil")
|
||||
}
|
||||
|
||||
// always skip when a DELETE operation received in mutation handler
|
||||
// describe in https://github.com/kubernetes-sigs/controller-runtime/issues/1762
|
||||
if req.Operation == admissionv1.Delete {
|
||||
return Response{AdmissionResponse: admissionv1.AdmissionResponse{
|
||||
Allowed: true,
|
||||
Result: &metav1.Status{
|
||||
Code: http.StatusOK,
|
||||
},
|
||||
}}
|
||||
}
|
||||
|
||||
// Get the object in the request
|
||||
obj := h.defaulter.DeepCopyObject().(Defaulter)
|
||||
if err := h.decoder.Decode(req, obj); err != nil {
|
||||
|
||||
15
vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter_custom.go
generated
vendored
15
vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/defaulter_custom.go
generated
vendored
@@ -19,11 +19,12 @@ package admission
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
admissionv1 "k8s.io/api/admission/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
@@ -61,6 +62,18 @@ func (h *defaulterForType) Handle(ctx context.Context, req Request) Response {
|
||||
panic("object should never be nil")
|
||||
}
|
||||
|
||||
// Always skip when a DELETE operation received in custom mutation handler.
|
||||
if req.Operation == admissionv1.Delete {
|
||||
return Response{AdmissionResponse: admissionv1.AdmissionResponse{
|
||||
Allowed: true,
|
||||
Result: &metav1.Status{
|
||||
Code: http.StatusOK,
|
||||
},
|
||||
}}
|
||||
}
|
||||
|
||||
ctx = NewContextWithRequest(ctx, req)
|
||||
|
||||
// Get the object in the request
|
||||
obj := h.object.DeepCopyObject()
|
||||
if err := h.decoder.Decode(req, obj); err != nil {
|
||||
|
||||
12
vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/http.go
generated
vendored
12
vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/http.go
generated
vendored
@@ -124,8 +124,16 @@ func (wh *Webhook) writeResponseTyped(w io.Writer, response Response, admRevGVK
|
||||
// writeAdmissionResponse writes ar to w.
|
||||
func (wh *Webhook) writeAdmissionResponse(w io.Writer, ar v1.AdmissionReview) {
|
||||
if err := json.NewEncoder(w).Encode(ar); err != nil {
|
||||
wh.log.Error(err, "unable to encode the response")
|
||||
wh.writeResponse(w, Errored(http.StatusInternalServerError, err))
|
||||
wh.log.Error(err, "unable to encode and write the response")
|
||||
// Since the `ar v1.AdmissionReview` is a clear and legal object,
|
||||
// it should not have problem to be marshalled into bytes.
|
||||
// The error here is probably caused by the abnormal HTTP connection,
|
||||
// e.g., broken pipe, so we can only write the error response once,
|
||||
// to avoid endless circular calling.
|
||||
serverError := Errored(http.StatusInternalServerError, err)
|
||||
if err = json.NewEncoder(w).Encode(v1.AdmissionReview{Response: &serverError.AdmissionResponse}); err != nil {
|
||||
wh.log.Error(err, "still unable to encode and write the InternalServerError response")
|
||||
}
|
||||
} else {
|
||||
res := ar.Response
|
||||
if log := wh.log; log.V(1).Enabled() {
|
||||
|
||||
2
vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator_custom.go
generated
vendored
2
vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/validator_custom.go
generated
vendored
@@ -64,6 +64,8 @@ func (h *validatorForType) Handle(ctx context.Context, req Request) Response {
|
||||
panic("object should never be nil")
|
||||
}
|
||||
|
||||
ctx = NewContextWithRequest(ctx, req)
|
||||
|
||||
// Get the object in the request
|
||||
obj := h.object.DeepCopyObject()
|
||||
|
||||
|
||||
43
vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/webhook.go
generated
vendored
43
vendor/sigs.k8s.io/controller-runtime/pkg/webhook/admission/webhook.go
generated
vendored
@@ -19,6 +19,7 @@ package admission
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
@@ -27,6 +28,7 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/json"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/internal/log"
|
||||
@@ -121,6 +123,9 @@ type Webhook struct {
|
||||
// and potentially patches to apply to the handler.
|
||||
Handler Handler
|
||||
|
||||
// RecoverPanic indicates whether the panic caused by webhook should be recovered.
|
||||
RecoverPanic bool
|
||||
|
||||
// WithContextFunc will allow you to take the http.Request.Context() and
|
||||
// add any additional information such as passing the request path or
|
||||
// headers thus allowing you to read them from within the handler
|
||||
@@ -138,11 +143,29 @@ func (wh *Webhook) InjectLogger(l logr.Logger) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// WithRecoverPanic takes a bool flag which indicates whether the panic caused by webhook should be recovered.
|
||||
func (wh *Webhook) WithRecoverPanic(recoverPanic bool) *Webhook {
|
||||
wh.RecoverPanic = recoverPanic
|
||||
return wh
|
||||
}
|
||||
|
||||
// Handle processes AdmissionRequest.
|
||||
// If the webhook is mutating type, it delegates the AdmissionRequest to each handler and merge the patches.
|
||||
// If the webhook is validating type, it delegates the AdmissionRequest to each handler and
|
||||
// deny the request if anyone denies.
|
||||
func (wh *Webhook) Handle(ctx context.Context, req Request) Response {
|
||||
func (wh *Webhook) Handle(ctx context.Context, req Request) (response Response) {
|
||||
if wh.RecoverPanic {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
for _, fn := range utilruntime.PanicHandlers {
|
||||
fn(r)
|
||||
}
|
||||
response = Errored(http.StatusInternalServerError, fmt.Errorf("panic: %v [recovered]", r))
|
||||
return
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
resp := wh.Handler.Handle(ctx, req)
|
||||
if err := resp.Complete(req); err != nil {
|
||||
wh.log.Error(err, "unable to encode response")
|
||||
@@ -253,3 +276,21 @@ func StandaloneWebhook(hook *Webhook, opts StandaloneOptions) (http.Handler, err
|
||||
}
|
||||
return metrics.InstrumentedHook(opts.MetricsPath, hook), nil
|
||||
}
|
||||
|
||||
// requestContextKey is how we find the admission.Request in a context.Context.
|
||||
type requestContextKey struct{}
|
||||
|
||||
// RequestFromContext returns an admission.Request from ctx.
|
||||
func RequestFromContext(ctx context.Context) (Request, error) {
|
||||
if v, ok := ctx.Value(requestContextKey{}).(Request); ok {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
return Request{}, errors.New("admission.Request not found in context")
|
||||
}
|
||||
|
||||
// NewContextWithRequest returns a new Context, derived from ctx, which carries the
|
||||
// provided admission.Request.
|
||||
func NewContextWithRequest(ctx context.Context, req Request) context.Context {
|
||||
return context.WithValue(ctx, requestContextKey{}, req)
|
||||
}
|
||||
|
||||
6
vendor/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/conversion.go
generated
vendored
6
vendor/sigs.k8s.io/controller-runtime/pkg/webhook/conversion/conversion.go
generated
vendored
@@ -69,6 +69,12 @@ func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if convertReview.Request == nil {
|
||||
log.Error(nil, "conversion request is nil")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// TODO(droot): may be move the conversion logic to a separate module to
|
||||
// decouple it from the http layer ?
|
||||
resp, err := wh.handleConvertRequest(convertReview.Request)
|
||||
|
||||
11
vendor/sigs.k8s.io/controller-runtime/pkg/webhook/server.go
generated
vendored
11
vendor/sigs.k8s.io/controller-runtime/pkg/webhook/server.go
generated
vendored
@@ -74,8 +74,12 @@ type Server struct {
|
||||
|
||||
// TLSVersion is the minimum version of TLS supported. Accepts
|
||||
// "", "1.0", "1.1", "1.2" and "1.3" only ("" is equivalent to "1.0" for backwards compatibility)
|
||||
// Deprecated: Use TLSOpts instead.
|
||||
TLSMinVersion string
|
||||
|
||||
// TLSOpts is used to allow configuring the TLS config used for the server
|
||||
TLSOpts []func(*tls.Config)
|
||||
|
||||
// WebhookMux is the multiplexer that handles different webhooks.
|
||||
WebhookMux *http.ServeMux
|
||||
|
||||
@@ -254,6 +258,11 @@ func (s *Server) Start(ctx context.Context) error {
|
||||
cfg.ClientAuth = tls.RequireAndVerifyClientCert
|
||||
}
|
||||
|
||||
// fallback TLS config ready, will now mutate if passer wants full control over it
|
||||
for _, op := range s.TLSOpts {
|
||||
op(cfg)
|
||||
}
|
||||
|
||||
listener, err := tls.Listen("tcp", net.JoinHostPort(s.Host, strconv.Itoa(s.Port)), cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -291,7 +300,7 @@ func (s *Server) Start(ctx context.Context) error {
|
||||
// server has been started.
|
||||
func (s *Server) StartedChecker() healthz.Checker {
|
||||
config := &tls.Config{
|
||||
InsecureSkipVerify: true, // nolint:gosec // config is used to connect to our own webhook port.
|
||||
InsecureSkipVerify: true, //nolint:gosec // config is used to connect to our own webhook port.
|
||||
}
|
||||
return func(req *http.Request) error {
|
||||
s.mu.Lock()
|
||||
|
||||
2
vendor/sigs.k8s.io/kubefed/pkg/apis/core/common/constants.go
generated
vendored
2
vendor/sigs.k8s.io/kubefed/pkg/apis/core/common/constants.go
generated
vendored
@@ -24,6 +24,8 @@ const (
|
||||
ClusterReady ClusterConditionType = "Ready"
|
||||
// ClusterOffline means the cluster is temporarily down or not reachable
|
||||
ClusterOffline ClusterConditionType = "Offline"
|
||||
// ClusterConfigMalformed means the cluster's configuration may be malformed.
|
||||
ClusterConfigMalformed ClusterConditionType = "ConfigMalformed"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
6
vendor/sigs.k8s.io/kubefed/pkg/apis/core/v1beta1/kubefedcluster_types.go
generated
vendored
6
vendor/sigs.k8s.io/kubefed/pkg/apis/core/v1beta1/kubefedcluster_types.go
generated
vendored
@@ -70,6 +70,9 @@ type LocalSecretReference struct {
|
||||
type KubeFedClusterStatus struct {
|
||||
// Conditions is an array of current cluster conditions.
|
||||
Conditions []ClusterCondition `json:"conditions"`
|
||||
// KubernetesVersion is the Kubernetes git version of the cluster.
|
||||
// +optional
|
||||
KubernetesVersion string `json:"kubernetesVersion,omitempty"`
|
||||
// Zones are the names of availability zones in which the nodes of the cluster exist, e.g. 'us-east1-a'.
|
||||
// +optional
|
||||
Zones []string `json:"zones,omitempty"`
|
||||
@@ -81,7 +84,8 @@ type KubeFedClusterStatus struct {
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:printcolumn:name=age,type=date,JSONPath=.metadata.creationTimestamp
|
||||
// +kubebuilder:printcolumn:name=ready,type=string,JSONPath=.status.conditions[?(@.type=='Ready')].status
|
||||
// +kubebuilder:resource:path=kubefedclusters
|
||||
// +kubebuilder:printcolumn:name=kubernetes-version,type=string,JSONPath=.status.kubernetesVersion
|
||||
// +kubebuilder:resource:path=kubefedclusters,shortName=kfc
|
||||
// +kubebuilder:subresource:status
|
||||
|
||||
// KubeFedCluster configures KubeFed to be aware of a Kubernetes
|
||||
|
||||
3
vendor/sigs.k8s.io/kubefed/pkg/apis/core/v1beta1/kubefedconfig_types.go
generated
vendored
3
vendor/sigs.k8s.io/kubefed/pkg/apis/core/v1beta1/kubefedconfig_types.go
generated
vendored
@@ -48,6 +48,9 @@ type DurationConfig struct {
|
||||
// Time to wait before giving up on an unhealthy cluster.
|
||||
// +optional
|
||||
UnavailableDelay *metav1.Duration `json:"unavailableDelay,omitempty"`
|
||||
// Time to wait for all caches to sync before exit.
|
||||
// +optional
|
||||
CacheSyncTimeout *metav1.Duration `json:"cacheSyncTimeout,omitempty"`
|
||||
}
|
||||
type LeaderElectConfig struct {
|
||||
// The duration that non-leader candidates will wait after observing a leadership
|
||||
|
||||
5
vendor/sigs.k8s.io/kubefed/pkg/apis/core/v1beta1/zz_generated.deepcopy.go
generated
vendored
5
vendor/sigs.k8s.io/kubefed/pkg/apis/core/v1beta1/zz_generated.deepcopy.go
generated
vendored
@@ -118,6 +118,11 @@ func (in *DurationConfig) DeepCopyInto(out *DurationConfig) {
|
||||
*out = new(v1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
if in.CacheSyncTimeout != nil {
|
||||
in, out := &in.CacheSyncTimeout, &out.CacheSyncTimeout
|
||||
*out = new(v1.Duration)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DurationConfig.
|
||||
|
||||
41
vendor/sigs.k8s.io/kubefed/pkg/controller/util/cluster_util.go
generated
vendored
41
vendor/sigs.k8s.io/kubefed/pkg/controller/util/cluster_util.go
generated
vendored
@@ -124,26 +124,31 @@ func CustomizeTLSTransport(fedCluster *fedv1b1.KubeFedCluster, clientConfig *res
|
||||
return errors.Errorf("Cluster %s transport error: %s", fedCluster.Name, err)
|
||||
}
|
||||
|
||||
err = CustomizeCertificateValidation(fedCluster, transportConfig)
|
||||
if err != nil {
|
||||
return errors.Errorf("Cluster %s custom certificate validation error: %s", fedCluster.Name, err)
|
||||
if transportConfig != nil {
|
||||
err = CustomizeCertificateValidation(fedCluster, transportConfig)
|
||||
if err != nil {
|
||||
return errors.Errorf("Cluster %s custom certificate validation error: %s", fedCluster.Name, err)
|
||||
}
|
||||
|
||||
// using the same defaults as http.DefaultTransport
|
||||
clientConfig.Transport = &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
DualStack: true,
|
||||
}).DialContext,
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
TLSClientConfig: transportConfig,
|
||||
}
|
||||
clientConfig.TLSClientConfig = restclient.TLSClientConfig{}
|
||||
} else {
|
||||
clientConfig.Insecure = true
|
||||
}
|
||||
|
||||
// using the same defaults as http.DefaultTransport
|
||||
clientConfig.Transport = &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
DualStack: true,
|
||||
}).DialContext,
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
TLSClientConfig: transportConfig,
|
||||
}
|
||||
clientConfig.TLSClientConfig = restclient.TLSClientConfig{}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
12
vendor/sigs.k8s.io/kubefed/pkg/controller/util/constants.go
generated
vendored
12
vendor/sigs.k8s.io/kubefed/pkg/controller/util/constants.go
generated
vendored
@@ -20,9 +20,11 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Providing 0 duration to an informer indicates that resync should be delayed as long as possible
|
||||
const (
|
||||
NoResyncPeriod time.Duration = 0 * time.Second
|
||||
// Providing 0 duration to an informer indicates that resync should be delayed as long as possible
|
||||
NoResyncPeriod = 0 * time.Second
|
||||
|
||||
SyncedPollPeriod = 10 * time.Second
|
||||
|
||||
NamespaceName = "namespaces"
|
||||
NamespaceKind = "Namespace"
|
||||
@@ -39,6 +41,12 @@ const (
|
||||
StatusField = "status"
|
||||
MetadataField = "metadata"
|
||||
|
||||
// Service fields
|
||||
HealthCheckNodePortField = "healthCheckNodePort"
|
||||
ClusterIPField = "clusterIP"
|
||||
ClusterIPsField = "clusterIPs"
|
||||
PortsField = "ports"
|
||||
|
||||
// ServiceAccount fields
|
||||
SecretsField = "secrets"
|
||||
|
||||
|
||||
1
vendor/sigs.k8s.io/kubefed/pkg/controller/util/controllerconfig.go
generated
vendored
1
vendor/sigs.k8s.io/kubefed/pkg/controller/util/controllerconfig.go
generated
vendored
@@ -72,6 +72,7 @@ type ControllerConfig struct {
|
||||
ClusterAvailableDelay time.Duration
|
||||
ClusterUnavailableDelay time.Duration
|
||||
MinimizeLatency bool
|
||||
CacheSyncTimeout time.Duration
|
||||
MaxConcurrentSyncReconciles int64
|
||||
MaxConcurrentStatusReconciles int64
|
||||
SkipAdoptingResources bool
|
||||
|
||||
35
vendor/sigs.k8s.io/kubefed/pkg/controller/util/federated_informer.go
generated
vendored
35
vendor/sigs.k8s.io/kubefed/pkg/controller/util/federated_informer.go
generated
vendored
@@ -534,33 +534,24 @@ func (fs *federatedStoreImpl) GetKeyFor(item interface{}) string {
|
||||
return key
|
||||
}
|
||||
|
||||
// Checks whether stores for all clusters form the lists (and only these) are there and
|
||||
// ClustersSynced checks whether stores for all clusters form the lists (and only these) are there and
|
||||
// are synced.
|
||||
func (fs *federatedStoreImpl) ClustersSynced(clusters []*fedv1b1.KubeFedCluster) bool {
|
||||
// Get the list of informers to check under a lock and check it outside.
|
||||
okSoFar, informersToCheck := func() (bool, []informer) {
|
||||
fs.federatedInformer.Lock()
|
||||
defer fs.federatedInformer.Unlock()
|
||||
fs.federatedInformer.Lock()
|
||||
defer fs.federatedInformer.Unlock()
|
||||
|
||||
if len(fs.federatedInformer.targetInformers) != len(clusters) {
|
||||
return false, []informer{}
|
||||
}
|
||||
informersToCheck := make([]informer, 0, len(clusters))
|
||||
for _, cluster := range clusters {
|
||||
if targetInformer, found := fs.federatedInformer.targetInformers[cluster.Name]; found {
|
||||
informersToCheck = append(informersToCheck, targetInformer)
|
||||
} else {
|
||||
return false, []informer{}
|
||||
}
|
||||
}
|
||||
return true, informersToCheck
|
||||
}()
|
||||
|
||||
if !okSoFar {
|
||||
if len(fs.federatedInformer.targetInformers) != len(clusters) {
|
||||
klog.V(4).Infof("The number of target informers mismatch with given clusters")
|
||||
return false
|
||||
}
|
||||
for _, informerToCheck := range informersToCheck {
|
||||
if !informerToCheck.controller.HasSynced() {
|
||||
for _, cluster := range clusters {
|
||||
if targetInformer, found := fs.federatedInformer.targetInformers[cluster.Name]; found {
|
||||
if !targetInformer.controller.HasSynced() {
|
||||
klog.V(4).Infof("Informer of cluster %q not synced", cluster.Name)
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
klog.V(4).Infof("Informer of cluster %q not found", cluster.Name)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
31
vendor/sigs.k8s.io/kubefed/pkg/controller/util/worker.go
generated
vendored
31
vendor/sigs.k8s.io/kubefed/pkg/controller/util/worker.go
generated
vendored
@@ -23,6 +23,8 @@ import (
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
runtimeclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"sigs.k8s.io/kubefed/pkg/metrics"
|
||||
)
|
||||
|
||||
type ReconcileFunc func(qualifiedName QualifiedName) ReconciliationStatus
|
||||
@@ -128,6 +130,8 @@ func (w *asyncWorker) EnqueueWithDelay(qualifiedName QualifiedName, delay time.D
|
||||
}
|
||||
|
||||
func (w *asyncWorker) Run(stopChan <-chan struct{}) {
|
||||
w.initMetrics()
|
||||
|
||||
StartBackoffGC(w.backoff, stopChan)
|
||||
w.deliverer.StartWithHandler(func(item *DelayingDelivererItem) {
|
||||
qualifiedName, ok := item.Value.(*QualifiedName)
|
||||
@@ -183,16 +187,41 @@ func (w *asyncWorker) reconcileOnce() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
metrics.ControllerRuntimeActiveWorkers.WithLabelValues(w.name).Add(1)
|
||||
defer metrics.ControllerRuntimeActiveWorkers.WithLabelValues(w.name).Add(-1)
|
||||
defer metrics.UpdateControllerRuntimeReconcileTimeFromStart(w.name, time.Now())
|
||||
|
||||
status := w.reconcile(qualifiedName)
|
||||
switch status {
|
||||
case StatusAllOK:
|
||||
break
|
||||
metrics.ControllerRuntimeReconcileTotal.WithLabelValues(w.name, labelSuccess).Inc()
|
||||
case StatusError:
|
||||
w.EnqueueForError(qualifiedName)
|
||||
metrics.ControllerRuntimeReconcileErrors.WithLabelValues(w.name).Inc()
|
||||
metrics.ControllerRuntimeReconcileTotal.WithLabelValues(w.name, labelError).Inc()
|
||||
case StatusNeedsRecheck:
|
||||
w.EnqueueForRetry(qualifiedName)
|
||||
metrics.ControllerRuntimeReconcileTotal.WithLabelValues(w.name, labelNeedsRecheck).Inc()
|
||||
case StatusNotSynced:
|
||||
w.EnqueueForClusterSync(qualifiedName)
|
||||
metrics.ControllerRuntimeReconcileTotal.WithLabelValues(w.name, labelNotSynced).Inc()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const (
|
||||
labelSuccess = "success"
|
||||
labelError = "error"
|
||||
labelNeedsRecheck = "needs_recheck"
|
||||
labelNotSynced = "not_synced"
|
||||
)
|
||||
|
||||
func (w *asyncWorker) initMetrics() {
|
||||
metrics.ControllerRuntimeActiveWorkers.WithLabelValues(w.name).Set(0)
|
||||
metrics.ControllerRuntimeReconcileErrors.WithLabelValues(w.name).Add(0)
|
||||
metrics.ControllerRuntimeReconcileTotal.WithLabelValues(w.name, labelSuccess).Add(0)
|
||||
metrics.ControllerRuntimeReconcileTotal.WithLabelValues(w.name, labelError).Add(0)
|
||||
metrics.ControllerRuntimeReconcileTotal.WithLabelValues(w.name, labelNeedsRecheck).Add(0)
|
||||
metrics.ControllerRuntimeReconcileTotal.WithLabelValues(w.name, labelNotSynced).Add(0)
|
||||
metrics.ControllerRuntimeWorkerCount.WithLabelValues(w.name).Set(float64(w.maxConcurrentReconciles))
|
||||
}
|
||||
|
||||
6
vendor/sigs.k8s.io/kubefed/pkg/kubefedctl/util/util.go
generated
vendored
6
vendor/sigs.k8s.io/kubefed/pkg/kubefedctl/util/util.go
generated
vendored
@@ -107,6 +107,12 @@ func ClusterServiceAccountName(joiningClusterName, hostClusterName string) strin
|
||||
return fmt.Sprintf("%s-%s", joiningClusterName, hostClusterName)
|
||||
}
|
||||
|
||||
// ClusterServiceAccountTokenSecretName returns the name of a service account token secret whose
|
||||
// credentials are used by the host cluster to access the client cluster.
|
||||
func ClusterServiceAccountTokenSecretName(joiningClusterName, hostClusterName string) string {
|
||||
return fmt.Sprintf("%s-%s", joiningClusterName, hostClusterName)
|
||||
}
|
||||
|
||||
// RoleName returns the name of a Role or ClusterRole and its
|
||||
// associated RoleBinding or ClusterRoleBinding that are used to allow
|
||||
// the service account to access necessary resources on the cluster.
|
||||
|
||||
61
vendor/sigs.k8s.io/kubefed/pkg/metrics/metrics.go
generated
vendored
61
vendor/sigs.k8s.io/kubefed/pkg/metrics/metrics.go
generated
vendored
@@ -20,6 +20,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/collectors"
|
||||
"k8s.io/klog/v2"
|
||||
"sigs.k8s.io/controller-runtime/pkg/metrics"
|
||||
)
|
||||
@@ -58,7 +59,7 @@ var (
|
||||
reconcileFederatedResourcesDuration = prometheus.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "reconcile_federated_resources_duration_seconds",
|
||||
Help: "Time taken to reconcile federated resources in the target clusters.",
|
||||
Help: "[Deprecated] Time taken to reconcile federated resources in the target clusters. Replaced by controller_runtime_reconcile_time_seconds.",
|
||||
Buckets: []float64{0.01, 0.05, 0.1, 0.5, 1.0, 2.5, 5.0, 7.5, 10.0, 12.5, 15.0, 17.5, 20.0, 22.5, 25.0, 27.5, 30.0, 50.0, 75.0, 100.0, 1000.0},
|
||||
},
|
||||
)
|
||||
@@ -90,7 +91,7 @@ var (
|
||||
controllerRuntimeReconcileDuration = prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "controller_runtime_reconcile_duration_seconds",
|
||||
Help: "Time taken by various parts of Kubefed controllers reconciliation loops.",
|
||||
Help: "[Deprecated] Time taken by various parts of Kubefed controllers reconciliation loops. Replaced by controller_runtime_reconcile_time_seconds.",
|
||||
Buckets: []float64{0.01, 0.05, 0.1, 0.5, 1.0, 2.5, 5.0, 7.5, 10.0, 12.5, 15.0, 17.5, 20.0, 22.5, 25.0, 27.5, 30.0, 50.0, 75.0, 100.0, 1000.0},
|
||||
}, []string{"controller"},
|
||||
)
|
||||
@@ -98,10 +99,37 @@ var (
|
||||
controllerRuntimeReconcileDurationSummary = prometheus.NewSummaryVec(
|
||||
prometheus.SummaryOpts{
|
||||
Name: "controller_runtime_reconcile_quantile_seconds",
|
||||
Help: "Quantiles of time taken by various parts of Kubefed controllers reconciliation loops.",
|
||||
Help: "[Deprecated] Quantiles of time taken by various parts of Kubefed controllers reconciliation loops. Replaced by controller_runtime_reconcile_time_seconds.",
|
||||
MaxAge: time.Hour,
|
||||
}, []string{"controller"},
|
||||
)
|
||||
|
||||
ControllerRuntimeReconcileTotal = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "controller_runtime_reconcile_total",
|
||||
Help: "Total number of reconciliations per controller",
|
||||
}, []string{"controller", "result"})
|
||||
|
||||
ControllerRuntimeReconcileErrors = prometheus.NewCounterVec(prometheus.CounterOpts{
|
||||
Name: "controller_runtime_reconcile_errors_total",
|
||||
Help: "Total number of reconciliation errors per controller",
|
||||
}, []string{"controller"})
|
||||
|
||||
ControllerRuntimeReconcileTime = prometheus.NewHistogramVec(prometheus.HistogramOpts{
|
||||
Name: "controller_runtime_reconcile_time_seconds",
|
||||
Help: "Length of time per reconciliation per controller",
|
||||
Buckets: []float64{0.005, 0.01, 0.025, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0,
|
||||
1.25, 1.5, 1.75, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 40, 50, 60},
|
||||
}, []string{"controller"})
|
||||
|
||||
ControllerRuntimeWorkerCount = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "controller_runtime_max_concurrent_reconciles",
|
||||
Help: "Maximum number of concurrent reconciles per controller",
|
||||
}, []string{"controller"})
|
||||
|
||||
ControllerRuntimeActiveWorkers = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "controller_runtime_active_workers",
|
||||
Help: "Number of currently used workers per controller",
|
||||
}, []string{"controller"})
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -117,6 +145,10 @@ const (
|
||||
// RegisterAll registers all metrics.
|
||||
func RegisterAll() {
|
||||
metrics.Registry.MustRegister(
|
||||
// expose process metrics like CPU, Memory, file descriptor usage etc.
|
||||
collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}),
|
||||
// expose Go runtime metrics like GC stats, memory stats etc.
|
||||
collectors.NewGoCollector(),
|
||||
kubefedClusterTotal,
|
||||
joinedClusterTotal,
|
||||
reconcileFederatedResourcesDuration,
|
||||
@@ -127,6 +159,11 @@ func RegisterAll() {
|
||||
dispatchOperationDuration,
|
||||
controllerRuntimeReconcileDuration,
|
||||
controllerRuntimeReconcileDurationSummary,
|
||||
ControllerRuntimeReconcileTotal,
|
||||
ControllerRuntimeReconcileErrors,
|
||||
ControllerRuntimeReconcileTime,
|
||||
ControllerRuntimeWorkerCount,
|
||||
ControllerRuntimeActiveWorkers,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -203,10 +240,20 @@ func UpdateControllerReconcileDurationFromStart(controller string, start time.Ti
|
||||
|
||||
// UpdateControllerReconcileDuration records the duration of the reconcile function of a controller
|
||||
func UpdateControllerReconcileDuration(controller string, duration time.Duration) {
|
||||
if duration > LogReconcileLongDurationThreshold {
|
||||
klog.V(4).Infof("Reconcile loop %s took %v to complete", controller, duration)
|
||||
}
|
||||
|
||||
controllerRuntimeReconcileDurationSummary.WithLabelValues(controller).Observe(duration.Seconds())
|
||||
controllerRuntimeReconcileDuration.WithLabelValues(controller).Observe(duration.Seconds())
|
||||
}
|
||||
|
||||
// UpdateControllerRuntimeReconcileTimeFromStart records the duration of the reconcile loop of a controller
|
||||
func UpdateControllerRuntimeReconcileTimeFromStart(controller string, start time.Time) {
|
||||
duration := time.Since(start)
|
||||
UpdateControllerRuntimeReconcileTime(controller, duration)
|
||||
}
|
||||
|
||||
// UpdateControllerRuntimeReconcileTime records the duration of the reconcile function of a controller
|
||||
func UpdateControllerRuntimeReconcileTime(controller string, duration time.Duration) {
|
||||
if duration > LogReconcileLongDurationThreshold {
|
||||
klog.V(4).Infof("Reconcile loop %s took %v to complete", controller, duration)
|
||||
}
|
||||
ControllerRuntimeReconcileTime.WithLabelValues(controller).Observe(duration.Seconds())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user