Upgrade k8s package verison (#5358)
* upgrade k8s package version Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io> * Script upgrade and code formatting. Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io> Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>
This commit is contained in:
17
vendor/github.com/operator-framework/helm-operator-plugins/pkg/client/actionclient.go
generated
vendored
17
vendor/github.com/operator-framework/helm-operator-plugins/pkg/client/actionclient.go
generated
vendored
@@ -44,7 +44,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"github.com/operator-framework/helm-operator-plugins/pkg/internal/sdk/controllerutil"
|
||||
"github.com/operator-framework/helm-operator-plugins/internal/sdk/controllerutil"
|
||||
"github.com/operator-framework/helm-operator-plugins/pkg/manifestutil"
|
||||
)
|
||||
|
||||
@@ -140,7 +140,7 @@ func (c *actionClient) Install(name, namespace string, chrt *chart.Chart, vals m
|
||||
// Only return an error about a rollback failure if the failure was
|
||||
// caused by something other than the release not being found.
|
||||
_, uninstallErr := c.Uninstall(name)
|
||||
if !errors.Is(uninstallErr, driver.ErrReleaseNotFound) {
|
||||
if uninstallErr != nil && !errors.Is(uninstallErr, driver.ErrReleaseNotFound) {
|
||||
return nil, fmt.Errorf("uninstall failed: %v: original install error: %w", uninstallErr, err)
|
||||
}
|
||||
}
|
||||
@@ -163,6 +163,7 @@ func (c *actionClient) Upgrade(name, namespace string, chrt *chart.Chart, vals m
|
||||
if rel != nil {
|
||||
rollback := action.NewRollback(c.conf)
|
||||
rollback.Force = true
|
||||
rollback.MaxHistory = upgrade.MaxHistory
|
||||
|
||||
// As of Helm 2.13, if Upgrade returns a non-nil release, that
|
||||
// means the release was also recorded in the release store.
|
||||
@@ -263,9 +264,17 @@ func createPatch(existing runtime.Object, expected *resource.Info) ([]byte, apit
|
||||
if err != nil {
|
||||
return nil, apitypes.StrategicMergePatchType, err
|
||||
}
|
||||
|
||||
patch, err := strategicpatch.CreateThreeWayMergePatch(expectedJSON, expectedJSON, existingJSON, patchMeta, true)
|
||||
return patch, apitypes.StrategicMergePatchType, err
|
||||
if err != nil {
|
||||
return nil, apitypes.StrategicMergePatchType, err
|
||||
}
|
||||
|
||||
// An empty patch could be in the form of "{}" which represents an empty map out of the 3-way merge;
|
||||
// filter them out here too to avoid sending the apiserver empty patch requests.
|
||||
if len(patch) == 0 || bytes.Equal(patch, []byte("{}")) {
|
||||
return nil, apitypes.StrategicMergePatchType, nil
|
||||
}
|
||||
return patch, apitypes.StrategicMergePatchType, nil
|
||||
}
|
||||
|
||||
func createJSONMergePatch(existingJSON, expectedJSON []byte) ([]byte, error) {
|
||||
|
||||
@@ -60,7 +60,7 @@ func (acg *actionConfigGetter) ActionConfigFor(obj client.Object) (*action.Confi
|
||||
|
||||
// Setup the debug log function that Helm will use
|
||||
debugLog := func(format string, v ...interface{}) {
|
||||
if acg.log != nil {
|
||||
if acg.log.GetSink() != nil {
|
||||
acg.log.V(1).Info(fmt.Sprintf(format, v...))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 The Operator-SDK 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 controllerutil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
)
|
||||
|
||||
var (
|
||||
AddFinalizer = controllerutil.AddFinalizer
|
||||
RemoveFinalizer = controllerutil.RemoveFinalizer
|
||||
ContainsFinalizer = func(obj metav1.Object, finalizer string) bool {
|
||||
for _, f := range obj.GetFinalizers() {
|
||||
if f == finalizer {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
)
|
||||
|
||||
func WaitForDeletion(ctx context.Context, cl client.Reader, o client.Object) error {
|
||||
key := client.ObjectKeyFromObject(o)
|
||||
|
||||
return wait.PollImmediateUntil(time.Millisecond*10, func() (bool, error) {
|
||||
err := cl.Get(ctx, key, o)
|
||||
if apierrors.IsNotFound(err) {
|
||||
return true, nil
|
||||
}
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return false, nil
|
||||
}, ctx.Done())
|
||||
}
|
||||
|
||||
func SupportsOwnerReference(restMapper meta.RESTMapper, owner, dependent client.Object) (bool, error) {
|
||||
ownerGVK := owner.GetObjectKind().GroupVersionKind()
|
||||
ownerMapping, err := restMapper.RESTMapping(ownerGVK.GroupKind(), ownerGVK.Version)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
depGVK := dependent.GetObjectKind().GroupVersionKind()
|
||||
depMapping, err := restMapper.RESTMapping(depGVK.GroupKind(), depGVK.Version)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
ownerClusterScoped := ownerMapping.Scope.Name() == meta.RESTScopeNameRoot
|
||||
ownerNamespace := owner.GetNamespace()
|
||||
depClusterScoped := depMapping.Scope.Name() == meta.RESTScopeNameRoot
|
||||
depNamespace := dependent.GetNamespace()
|
||||
|
||||
if ownerClusterScoped {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if depClusterScoped {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if ownerNamespace != depNamespace {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
kubeclock "k8s.io/apimachinery/pkg/util/clock"
|
||||
kubeclock "k8s.io/utils/clock"
|
||||
)
|
||||
|
||||
// clock is used to set status condition timestamps.
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
|
||||
"github.com/operator-framework/helm-operator-plugins/pkg/internal/sdk/status"
|
||||
"github.com/operator-framework/helm-operator-plugins/pkg/internal/status"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
61
vendor/github.com/operator-framework/helm-operator-plugins/pkg/reconciler/internal/diff/diff.go
generated
vendored
Normal file
61
vendor/github.com/operator-framework/helm-operator-plugins/pkg/reconciler/internal/diff/diff.go
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
// Copyright 2022 The Operator-SDK 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 diff
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/sergi/go-diff/diffmatchpatch"
|
||||
)
|
||||
|
||||
// Generate generates a diff between a and b, in color.
|
||||
func Generate(a, b string) string {
|
||||
dmp := diffmatchpatch.New()
|
||||
|
||||
wSrc, wDst, warray := dmp.DiffLinesToRunes(a, b)
|
||||
diffs := dmp.DiffMainRunes(wSrc, wDst, false)
|
||||
diffs = dmp.DiffCharsToLines(diffs, warray)
|
||||
var buff bytes.Buffer
|
||||
for _, diff := range diffs {
|
||||
text := diff.Text
|
||||
|
||||
switch diff.Type {
|
||||
case diffmatchpatch.DiffInsert:
|
||||
_, _ = buff.WriteString("\x1b[32m")
|
||||
_, _ = buff.WriteString(prefixLines(text, "+"))
|
||||
_, _ = buff.WriteString("\x1b[0m")
|
||||
case diffmatchpatch.DiffDelete:
|
||||
_, _ = buff.WriteString("\x1b[31m")
|
||||
_, _ = buff.WriteString(prefixLines(text, "-"))
|
||||
_, _ = buff.WriteString("\x1b[0m")
|
||||
case diffmatchpatch.DiffEqual:
|
||||
_, _ = buff.WriteString(prefixLines(text, " "))
|
||||
}
|
||||
}
|
||||
return buff.String()
|
||||
}
|
||||
|
||||
func prefixLines(s, prefix string) string {
|
||||
var buf bytes.Buffer
|
||||
lines := strings.Split(s, "\n")
|
||||
ls := regexp.MustCompile("^")
|
||||
for _, line := range lines[:len(lines)-1] {
|
||||
buf.WriteString(ls.ReplaceAllString(line, prefix))
|
||||
buf.WriteString("\n")
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
@@ -25,15 +25,16 @@ import (
|
||||
"helm.sh/helm/v3/pkg/releaseutil"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller"
|
||||
"sigs.k8s.io/controller-runtime/pkg/handler"
|
||||
"sigs.k8s.io/controller-runtime/pkg/source"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"github.com/operator-framework/helm-operator-plugins/internal/sdk/controllerutil"
|
||||
"github.com/operator-framework/helm-operator-plugins/pkg/hook"
|
||||
"github.com/operator-framework/helm-operator-plugins/pkg/internal/sdk/controllerutil"
|
||||
"github.com/operator-framework/helm-operator-plugins/pkg/internal/sdk/predicate"
|
||||
"github.com/operator-framework/helm-operator-plugins/pkg/internal/predicate"
|
||||
"github.com/operator-framework/helm-operator-plugins/pkg/manifestutil"
|
||||
)
|
||||
|
||||
@@ -69,32 +70,65 @@ func (d *dependentResourceWatcher) Exec(owner *unstructured.Unstructured, rel re
|
||||
}
|
||||
|
||||
depGVK := obj.GroupVersionKind()
|
||||
if _, ok := d.watches[depGVK]; ok || depGVK.Empty() {
|
||||
if depGVK.Empty() {
|
||||
continue
|
||||
}
|
||||
|
||||
useOwnerRef, err := controllerutil.SupportsOwnerReference(d.restMapper, owner, &obj)
|
||||
if err != nil {
|
||||
return err
|
||||
var setWatchOnResource = func(dependent runtime.Object) error {
|
||||
unstructuredObj := dependent.(*unstructured.Unstructured)
|
||||
gvkDependent := unstructuredObj.GroupVersionKind()
|
||||
|
||||
if gvkDependent.Empty() {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, ok := d.watches[gvkDependent]
|
||||
if ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
useOwnerRef, err := controllerutil.SupportsOwnerReference(d.restMapper, owner, unstructuredObj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if useOwnerRef && !manifestutil.HasResourcePolicyKeep(unstructuredObj.GetAnnotations()) { // Setup watch using owner references.
|
||||
if err := d.controller.Watch(&source.Kind{Type: unstructuredObj}, &handler.EnqueueRequestForOwner{
|
||||
OwnerType: owner,
|
||||
IsController: true,
|
||||
}, dependentPredicate); err != nil {
|
||||
return err
|
||||
}
|
||||
} else { // Setup watch using annotations.
|
||||
if err := d.controller.Watch(&source.Kind{Type: unstructuredObj}, &sdkhandler.EnqueueRequestForAnnotation{
|
||||
Type: owner.GetObjectKind().GroupVersionKind().GroupKind(),
|
||||
}, dependentPredicate); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
d.watches[depGVK] = struct{}{}
|
||||
log.V(1).Info("Watching dependent resource", "dependentAPIVersion", depGVK.GroupVersion(), "dependentKind", depGVK.Kind)
|
||||
return nil
|
||||
}
|
||||
|
||||
if useOwnerRef && !manifestutil.HasResourcePolicyKeep(obj.GetAnnotations()) {
|
||||
if err := d.controller.Watch(&source.Kind{Type: &obj}, &handler.EnqueueRequestForOwner{
|
||||
OwnerType: owner,
|
||||
IsController: true,
|
||||
}, dependentPredicate); err != nil {
|
||||
return err
|
||||
// List is not actually a resource and therefore cannot have a
|
||||
// watch on it. The watch will be on the kinds listed in the list
|
||||
// and will therefore need to be handled individually.
|
||||
listGVK := schema.GroupVersionKind{Group: "", Version: "v1", Kind: "List"}
|
||||
if depGVK == listGVK {
|
||||
errListItem := obj.EachListItem(func(o runtime.Object) error {
|
||||
return setWatchOnResource(o)
|
||||
})
|
||||
if errListItem != nil {
|
||||
return errListItem
|
||||
}
|
||||
} else {
|
||||
if err := d.controller.Watch(&source.Kind{Type: &obj}, &sdkhandler.EnqueueRequestForAnnotation{
|
||||
Type: owner.GetObjectKind().GroupVersionKind().GroupKind(),
|
||||
}, dependentPredicate); err != nil {
|
||||
err := setWatchOnResource(&obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
d.watches[depGVK] = struct{}{}
|
||||
log.V(1).Info("Watching dependent resource", "dependentAPIVersion", depGVK.GroupVersion(), "dependentKind", depGVK.Kind)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -26,8 +26,8 @@ import (
|
||||
"k8s.io/client-go/util/retry"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/operator-framework/helm-operator-plugins/pkg/internal/sdk/controllerutil"
|
||||
"github.com/operator-framework/helm-operator-plugins/pkg/internal/sdk/status"
|
||||
"github.com/operator-framework/helm-operator-plugins/internal/sdk/controllerutil"
|
||||
"github.com/operator-framework/helm-operator-plugins/pkg/internal/status"
|
||||
)
|
||||
|
||||
func New(client client.Client) Updater {
|
||||
|
||||
@@ -17,21 +17,37 @@ limitations under the License.
|
||||
package values
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"helm.sh/helm/v3/pkg/chartutil"
|
||||
"helm.sh/helm/v3/pkg/strvals"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"os"
|
||||
|
||||
"github.com/operator-framework/helm-operator-plugins/pkg/values"
|
||||
)
|
||||
|
||||
type Values struct {
|
||||
m map[string]interface{}
|
||||
var DefaultMapper = values.MapperFunc(func(v chartutil.Values) chartutil.Values { return v })
|
||||
|
||||
var DefaultTranslator = values.TranslatorFunc(func(ctx context.Context, u *unstructured.Unstructured) (chartutil.Values, error) {
|
||||
return getSpecMap(u)
|
||||
})
|
||||
|
||||
func ApplyOverrides(overrideValues map[string]string, obj *unstructured.Unstructured) error {
|
||||
specMap, err := getSpecMap(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for inK, inV := range overrideValues {
|
||||
val := fmt.Sprintf("%s=%s", inK, os.ExpandEnv(inV))
|
||||
if err := strvals.ParseInto(val, specMap); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func FromUnstructured(obj *unstructured.Unstructured) (*Values, error) {
|
||||
func getSpecMap(obj *unstructured.Unstructured) (map[string]interface{}, error) {
|
||||
if obj == nil || obj.Object == nil {
|
||||
return nil, fmt.Errorf("nil object")
|
||||
}
|
||||
@@ -43,28 +59,5 @@ func FromUnstructured(obj *unstructured.Unstructured) (*Values, error) {
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("spec must be a map")
|
||||
}
|
||||
return New(specMap), nil
|
||||
return specMap, nil
|
||||
}
|
||||
|
||||
func New(m map[string]interface{}) *Values {
|
||||
return &Values{m: m}
|
||||
}
|
||||
|
||||
func (v *Values) Map() map[string]interface{} {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
return v.m
|
||||
}
|
||||
|
||||
func (v *Values) ApplyOverrides(in map[string]string) error {
|
||||
for inK, inV := range in {
|
||||
val := fmt.Sprintf("%s=%s", inK, os.ExpandEnv(inV))
|
||||
if err := strvals.ParseInto(val, v.m); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var DefaultMapper = values.MapperFunc(func(v chartutil.Values) chartutil.Values { return v })
|
||||
|
||||
196
vendor/github.com/operator-framework/helm-operator-plugins/pkg/reconciler/reconciler.go
generated
vendored
196
vendor/github.com/operator-framework/helm-operator-plugins/pkg/reconciler/reconciler.go
generated
vendored
@@ -42,13 +42,16 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller"
|
||||
"sigs.k8s.io/controller-runtime/pkg/handler"
|
||||
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||
ctrlpredicate "sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||
"sigs.k8s.io/controller-runtime/pkg/source"
|
||||
|
||||
"github.com/operator-framework/helm-operator-plugins/internal/sdk/controllerutil"
|
||||
"github.com/operator-framework/helm-operator-plugins/pkg/annotation"
|
||||
helmclient "github.com/operator-framework/helm-operator-plugins/pkg/client"
|
||||
"github.com/operator-framework/helm-operator-plugins/pkg/hook"
|
||||
"github.com/operator-framework/helm-operator-plugins/pkg/internal/sdk/controllerutil"
|
||||
"github.com/operator-framework/helm-operator-plugins/pkg/reconciler/internal/conditions"
|
||||
"github.com/operator-framework/helm-operator-plugins/pkg/reconciler/internal/diff"
|
||||
internalhook "github.com/operator-framework/helm-operator-plugins/pkg/reconciler/internal/hook"
|
||||
"github.com/operator-framework/helm-operator-plugins/pkg/reconciler/internal/updater"
|
||||
internalvalues "github.com/operator-framework/helm-operator-plugins/pkg/reconciler/internal/values"
|
||||
@@ -61,18 +64,22 @@ const uninstallFinalizer = "uninstall-helm-release"
|
||||
type Reconciler struct {
|
||||
client client.Client
|
||||
actionClientGetter helmclient.ActionClientGetter
|
||||
valueMapper values.Mapper
|
||||
valueTranslator values.Translator
|
||||
valueMapper values.Mapper // nolint:staticcheck
|
||||
eventRecorder record.EventRecorder
|
||||
preHooks []hook.PreHook
|
||||
postHooks []hook.PostHook
|
||||
|
||||
log logr.Logger
|
||||
gvk *schema.GroupVersionKind
|
||||
chrt *chart.Chart
|
||||
overrideValues map[string]string
|
||||
skipDependentWatches bool
|
||||
maxConcurrentReconciles int
|
||||
reconcilePeriod time.Duration
|
||||
log logr.Logger
|
||||
gvk *schema.GroupVersionKind
|
||||
chrt *chart.Chart
|
||||
selectorPredicate predicate.Predicate
|
||||
overrideValues map[string]string
|
||||
skipDependentWatches bool
|
||||
maxConcurrentReconciles int
|
||||
reconcilePeriod time.Duration
|
||||
maxHistory int
|
||||
skipPrimaryGVKSchemeRegistration bool
|
||||
|
||||
annotSetupOnce sync.Once
|
||||
annotations map[string]struct{}
|
||||
@@ -126,7 +133,9 @@ func (r *Reconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||
controllerName := fmt.Sprintf("%v-controller", strings.ToLower(r.gvk.Kind))
|
||||
|
||||
r.addDefaults(mgr, controllerName)
|
||||
r.setupScheme(mgr)
|
||||
if !r.skipPrimaryGVKSchemeRegistration {
|
||||
r.setupScheme(mgr)
|
||||
}
|
||||
|
||||
c, err := controller.New(controllerName, mgr, controller.Options{Reconciler: r, MaxConcurrentReconciles: r.maxConcurrentReconciles})
|
||||
if err != nil {
|
||||
@@ -230,8 +239,8 @@ func WithOverrideValues(overrides map[string]string) Option {
|
||||
// Validate that overrides can be parsed and applied
|
||||
// so that we fail fast during operator setup rather
|
||||
// than during the first reconciliation.
|
||||
m := internalvalues.New(map[string]interface{}{})
|
||||
if err := m.ApplyOverrides(overrides); err != nil {
|
||||
obj := &unstructured.Unstructured{Object: map[string]interface{}{"spec": map[string]interface{}{}}}
|
||||
if err := internalvalues.ApplyOverrides(overrides, obj); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -252,6 +261,52 @@ func SkipDependentWatches(skip bool) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// SkipPrimaryGVKSchemeRegistration is an Option that allows to disable the default behaviour of
|
||||
// registering unstructured.Unstructured as underlying type for the GVK scheme.
|
||||
//
|
||||
// Disabling this built-in registration is necessary when building operators
|
||||
// for which it is desired to have the underlying GVK scheme backed by a
|
||||
// custom struct type.
|
||||
//
|
||||
// Example for using a custom type for the GVK scheme instead of unstructured.Unstructured:
|
||||
//
|
||||
// // Define custom type for GVK scheme.
|
||||
// //+kubebuilder:object:root=true
|
||||
// type Custom struct {
|
||||
// // [...]
|
||||
// }
|
||||
//
|
||||
// // Register custom type along with common meta types in scheme.
|
||||
// scheme := runtime.NewScheme()
|
||||
// scheme.AddKnownTypes(SchemeGroupVersion, &Custom{})
|
||||
// metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
//
|
||||
// // Create new manager using the controller-runtime, injecting above scheme.
|
||||
// options := ctrl.Options{
|
||||
// Scheme = scheme,
|
||||
// // [...]
|
||||
// }
|
||||
// mgr, err := ctrl.NewManager(config, options)
|
||||
//
|
||||
// // Create reconciler with generic scheme registration being disabled.
|
||||
// r, err := reconciler.New(
|
||||
// reconciler.WithChart(chart),
|
||||
// reconciler.SkipPrimaryGVKSchemeRegistration(true),
|
||||
// // [...]
|
||||
// )
|
||||
//
|
||||
// // Setup reconciler with above manager.
|
||||
// err = r.SetupWithManager(mgr)
|
||||
//
|
||||
// By default, skipping of the generic scheme setup is disabled, which means that
|
||||
// unstructured.Unstructured is used for the GVK scheme.
|
||||
func SkipPrimaryGVKSchemeRegistration(skip bool) Option {
|
||||
return func(r *Reconciler) error {
|
||||
r.skipPrimaryGVKSchemeRegistration = skip
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithMaxConcurrentReconciles is an Option that configures the number of
|
||||
// concurrent reconciles that the controller will run.
|
||||
//
|
||||
@@ -280,6 +335,18 @@ func WithReconcilePeriod(rp time.Duration) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithMaxReleaseHistory specifies the maximum size of the Helm release history maintained
|
||||
// on upgrades/rollbacks. Zero (default) means unlimited.
|
||||
func WithMaxReleaseHistory(maxHistory int) Option {
|
||||
return func(r *Reconciler) error {
|
||||
if maxHistory < 0 {
|
||||
return errors.New("maximum Helm release history size must not be negative")
|
||||
}
|
||||
r.maxHistory = maxHistory
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithInstallAnnotations is an Option that configures Install annotations
|
||||
// to enable custom action.Install fields to be set based on the value of
|
||||
// annotations found in the custom resource watched by this reconciler.
|
||||
@@ -362,8 +429,36 @@ func WithPostHook(h hook.PostHook) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithValueTranslator is an Option that configures a function that translates a
|
||||
// custom resource to the values passed to Helm.
|
||||
// Use this if you need to customize the logic that translates your custom resource to Helm values.
|
||||
// If you wish to, you can convert the Unstructured that is passed to your Translator to your own
|
||||
// Custom Resource struct like this:
|
||||
//
|
||||
// import "k8s.io/apimachinery/pkg/runtime"
|
||||
// foo := your.Foo{}
|
||||
// if err = runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &foo); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// // work with the type-safe foo
|
||||
//
|
||||
// Alternatively, your translator can also work similarly to a Mapper, by accessing the spec with:
|
||||
//
|
||||
// u.Object["spec"].(map[string]interface{})
|
||||
func WithValueTranslator(t values.Translator) Option {
|
||||
return func(r *Reconciler) error {
|
||||
r.valueTranslator = t
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithValueMapper is an Option that configures a function that maps values
|
||||
// from a custom resource spec to the values passed to Helm
|
||||
// from a custom resource spec to the values passed to Helm.
|
||||
// Use this if you want to apply a transformation on the values obtained from your custom resource, before
|
||||
// they are passed to Helm.
|
||||
//
|
||||
// Deprecated: Use WithValueTranslator instead.
|
||||
// WithValueMapper will be removed in a future release.
|
||||
func WithValueMapper(m values.Mapper) Option {
|
||||
return func(r *Reconciler) error {
|
||||
r.valueMapper = m
|
||||
@@ -371,6 +466,19 @@ func WithValueMapper(m values.Mapper) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithSelector is an Option that configures the reconciler to creates a
|
||||
// predicate that is used to filter resources based on the specified selector
|
||||
func WithSelector(s metav1.LabelSelector) Option {
|
||||
return func(r *Reconciler) error {
|
||||
p, err := ctrlpredicate.LabelSelectorPredicate(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.selectorPredicate = p
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Reconcile reconciles a CR that defines a Helm v3 release.
|
||||
//
|
||||
// - If a release does not exist for this CR, a new release is installed.
|
||||
@@ -397,11 +505,13 @@ func WithValueMapper(m values.Mapper) Option {
|
||||
// - Irreconcilable - an error occurred during reconciliation
|
||||
func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (res ctrl.Result, err error) {
|
||||
log := r.log.WithValues(strings.ToLower(r.gvk.Kind), req.NamespacedName)
|
||||
log.V(1).Info("Reconciliation triggered")
|
||||
|
||||
obj := &unstructured.Unstructured{}
|
||||
obj.SetGroupVersionKind(*r.gvk)
|
||||
err = r.client.Get(ctx, req.NamespacedName, obj)
|
||||
if apierrors.IsNotFound(err) {
|
||||
log.V(1).Info("Resource %s/%s not found, nothing to do", req.NamespacedName.Namespace, req.NamespacedName.Name)
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
if err != nil {
|
||||
@@ -458,7 +568,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (res ctrl.
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
vals, err := r.getValues(obj)
|
||||
vals, err := r.getValues(ctx, obj)
|
||||
if err != nil {
|
||||
u.UpdateStatus(
|
||||
updater.EnsureCondition(conditions.Irreconcilable(corev1.ConditionTrue, conditions.ReasonErrorGettingValues, err)),
|
||||
@@ -521,15 +631,15 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (res ctrl.
|
||||
return ctrl.Result{RequeueAfter: r.reconcilePeriod}, nil
|
||||
}
|
||||
|
||||
func (r *Reconciler) getValues(obj *unstructured.Unstructured) (chartutil.Values, error) {
|
||||
crVals, err := internalvalues.FromUnstructured(obj)
|
||||
func (r *Reconciler) getValues(ctx context.Context, obj *unstructured.Unstructured) (chartutil.Values, error) {
|
||||
if err := internalvalues.ApplyOverrides(r.overrideValues, obj); err != nil {
|
||||
return chartutil.Values{}, err
|
||||
}
|
||||
vals, err := r.valueTranslator.Translate(ctx, obj)
|
||||
if err != nil {
|
||||
return chartutil.Values{}, err
|
||||
}
|
||||
if err := crVals.ApplyOverrides(r.overrideValues); err != nil {
|
||||
return chartutil.Values{}, err
|
||||
}
|
||||
vals := r.valueMapper.Map(crVals.Map())
|
||||
vals = r.valueMapper.Map(vals)
|
||||
vals, err = chartutil.CoalesceValues(r.chrt, vals)
|
||||
if err != nil {
|
||||
return chartutil.Values{}, err
|
||||
@@ -592,6 +702,12 @@ func (r *Reconciler) getReleaseState(client helmclient.ActionInterface, obj meta
|
||||
}
|
||||
|
||||
var opts []helmclient.UpgradeOption
|
||||
if r.maxHistory > 0 {
|
||||
opts = append(opts, func(u *action.Upgrade) error {
|
||||
u.MaxHistory = r.maxHistory
|
||||
return nil
|
||||
})
|
||||
}
|
||||
for name, annot := range r.upgradeAnnotations {
|
||||
if v, ok := obj.GetAnnotations()[name]; ok {
|
||||
opts = append(opts, annot.UpgradeOption(v))
|
||||
@@ -631,17 +747,35 @@ func (r *Reconciler) doInstall(actionClient helmclient.ActionInterface, u *updat
|
||||
r.reportOverrideEvents(obj)
|
||||
|
||||
log.Info("Release installed", "name", rel.Name, "version", rel.Version)
|
||||
|
||||
// If log verbosity is higher, output Helm Release Manifest that was installed
|
||||
if log.V(4).Enabled() {
|
||||
fmt.Println(diff.Generate("", rel.Manifest))
|
||||
}
|
||||
|
||||
return rel, nil
|
||||
}
|
||||
|
||||
func (r *Reconciler) doUpgrade(actionClient helmclient.ActionInterface, u *updater.Updater, obj *unstructured.Unstructured, vals map[string]interface{}, log logr.Logger) (*release.Release, error) {
|
||||
var opts []helmclient.UpgradeOption
|
||||
if r.maxHistory > 0 {
|
||||
opts = append(opts, func(u *action.Upgrade) error {
|
||||
u.MaxHistory = r.maxHistory
|
||||
return nil
|
||||
})
|
||||
}
|
||||
for name, annot := range r.upgradeAnnotations {
|
||||
if v, ok := obj.GetAnnotations()[name]; ok {
|
||||
opts = append(opts, annot.UpgradeOption(v))
|
||||
}
|
||||
}
|
||||
|
||||
// Get the current release so we can compare the new release in the diff if the diff is being logged.
|
||||
curRel, err := actionClient.Get(obj.GetName())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get the current Helm Release: %w", err)
|
||||
}
|
||||
|
||||
rel, err := actionClient.Upgrade(obj.GetName(), obj.GetNamespace(), r.chrt, vals, opts...)
|
||||
if err != nil {
|
||||
u.UpdateStatus(
|
||||
@@ -653,6 +787,11 @@ func (r *Reconciler) doUpgrade(actionClient helmclient.ActionInterface, u *updat
|
||||
r.reportOverrideEvents(obj)
|
||||
|
||||
log.Info("Release upgraded", "name", rel.Name, "version", rel.Version)
|
||||
|
||||
// If log verbosity is higher, output upgraded Helm Release Manifest
|
||||
if log.V(4).Enabled() {
|
||||
fmt.Println(diff.Generate(curRel.Manifest, rel.Manifest))
|
||||
}
|
||||
return rel, nil
|
||||
}
|
||||
|
||||
@@ -702,6 +841,11 @@ func (r *Reconciler) doUninstall(actionClient helmclient.ActionInterface, u *upd
|
||||
return err
|
||||
} else {
|
||||
log.Info("Release uninstalled", "name", resp.Release.Name, "version", resp.Release.Version)
|
||||
|
||||
// If log verbosity is higher, output Helm Release Manifest that was uninstalled
|
||||
if log.V(4).Enabled() {
|
||||
fmt.Println(diff.Generate(resp.Release.Manifest, ""))
|
||||
}
|
||||
}
|
||||
u.Update(updater.RemoveFinalizer(uninstallFinalizer))
|
||||
u.UpdateStatus(
|
||||
@@ -726,7 +870,7 @@ func (r *Reconciler) addDefaults(mgr ctrl.Manager, controllerName string) {
|
||||
if r.client == nil {
|
||||
r.client = mgr.GetClient()
|
||||
}
|
||||
if r.log == nil {
|
||||
if r.log.GetSink() == nil {
|
||||
r.log = ctrl.Log.WithName("controllers").WithName("Helm")
|
||||
}
|
||||
if r.actionClientGetter == nil {
|
||||
@@ -736,6 +880,9 @@ func (r *Reconciler) addDefaults(mgr ctrl.Manager, controllerName string) {
|
||||
if r.eventRecorder == nil {
|
||||
r.eventRecorder = mgr.GetEventRecorderFor(controllerName)
|
||||
}
|
||||
if r.valueTranslator == nil {
|
||||
r.valueTranslator = internalvalues.DefaultTranslator
|
||||
}
|
||||
if r.valueMapper == nil {
|
||||
r.valueMapper = internalvalues.DefaultMapper
|
||||
}
|
||||
@@ -749,9 +896,16 @@ func (r *Reconciler) setupScheme(mgr ctrl.Manager) {
|
||||
func (r *Reconciler) setupWatches(mgr ctrl.Manager, c controller.Controller) error {
|
||||
obj := &unstructured.Unstructured{}
|
||||
obj.SetGroupVersionKind(*r.gvk)
|
||||
|
||||
var preds []ctrlpredicate.Predicate
|
||||
if r.selectorPredicate != nil {
|
||||
preds = append(preds, r.selectorPredicate)
|
||||
}
|
||||
|
||||
if err := c.Watch(
|
||||
&source.Kind{Type: obj},
|
||||
&sdkhandler.InstrumentedEnqueueRequestForObject{},
|
||||
preds...,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
22
vendor/github.com/operator-framework/helm-operator-plugins/pkg/values/values.go
generated
vendored
22
vendor/github.com/operator-framework/helm-operator-plugins/pkg/values/values.go
generated
vendored
@@ -17,9 +17,14 @@ limitations under the License.
|
||||
package values
|
||||
|
||||
import (
|
||||
"context"
|
||||
"helm.sh/helm/v3/pkg/chartutil"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
)
|
||||
|
||||
// Mapper is an interface expected by the reconciler.WithValueMapper option.
|
||||
//
|
||||
// Deprecated: use Translator instead.
|
||||
type Mapper interface {
|
||||
Map(chartutil.Values) chartutil.Values
|
||||
}
|
||||
@@ -29,3 +34,20 @@ type MapperFunc func(chartutil.Values) chartutil.Values
|
||||
func (m MapperFunc) Map(v chartutil.Values) chartutil.Values {
|
||||
return m(v)
|
||||
}
|
||||
|
||||
// Translator is an interface expected by the reconciler.WithValueTranslator option.
|
||||
//
|
||||
// Translate should return helm values based on the content of the unstructured object
|
||||
// which is being reconciled.
|
||||
//
|
||||
// See also the option documentation.
|
||||
type Translator interface {
|
||||
Translate(ctx context.Context, unstructured *unstructured.Unstructured) (chartutil.Values, error)
|
||||
}
|
||||
|
||||
// TranslatorFunc is a helper type for passing a function as a Translator.
|
||||
type TranslatorFunc func(context.Context, *unstructured.Unstructured) (chartutil.Values, error)
|
||||
|
||||
func (t TranslatorFunc) Translate(ctx context.Context, u *unstructured.Unstructured) (chartutil.Values, error) {
|
||||
return t(ctx, u)
|
||||
}
|
||||
|
||||
76
vendor/github.com/operator-framework/helm-operator-plugins/pkg/watches/watches.go
generated
vendored
76
vendor/github.com/operator-framework/helm-operator-plugins/pkg/watches/watches.go
generated
vendored
@@ -15,11 +15,15 @@
|
||||
package watches
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"text/template"
|
||||
|
||||
sprig "github.com/go-task/slim-sprig"
|
||||
"helm.sh/helm/v3/pkg/chart"
|
||||
"helm.sh/helm/v3/pkg/chart/loader"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -31,12 +35,12 @@ type Watch struct {
|
||||
schema.GroupVersionKind `json:",inline"`
|
||||
ChartPath string `json:"chart"`
|
||||
|
||||
WatchDependentResources *bool `json:"watchDependentResources,omitempty"`
|
||||
OverrideValues map[string]string `json:"overrideValues,omitempty"`
|
||||
ReconcilePeriod *metav1.Duration `json:"reconcilePeriod,omitempty"`
|
||||
MaxConcurrentReconciles *int `json:"maxConcurrentReconciles,omitempty"`
|
||||
|
||||
Chart *chart.Chart `json:"-"`
|
||||
WatchDependentResources *bool `json:"watchDependentResources,omitempty"`
|
||||
OverrideValues map[string]string `json:"overrideValues,omitempty"`
|
||||
ReconcilePeriod *metav1.Duration `json:"reconcilePeriod,omitempty"`
|
||||
MaxConcurrentReconciles *int `json:"maxConcurrentReconciles,omitempty"`
|
||||
Selector *metav1.LabelSelector `json:"selector,omitempty"`
|
||||
Chart *chart.Chart `json:"-"`
|
||||
}
|
||||
|
||||
// Load loads a slice of Watches from the watch file at `path`. For each entry
|
||||
@@ -44,7 +48,22 @@ type Watch struct {
|
||||
// encountered loading the file or verifying the configuration, it will be
|
||||
// returned.
|
||||
func Load(path string) ([]Watch, error) {
|
||||
b, err := ioutil.ReadFile(path)
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not open watches file: %w", err)
|
||||
}
|
||||
w, err := LoadReader(f)
|
||||
|
||||
// Make sure to close the file, regardless of the error returned by
|
||||
// LoadReader.
|
||||
if err := f.Close(); err != nil {
|
||||
return nil, fmt.Errorf("could not close watches file: %w", err)
|
||||
}
|
||||
return w, err
|
||||
}
|
||||
|
||||
func LoadReader(reader io.Reader) ([]Watch, error) {
|
||||
b, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -55,10 +74,12 @@ func Load(path string) ([]Watch, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
watchesMap := make(map[schema.GroupVersionKind]Watch)
|
||||
watchesMap := make(map[schema.GroupVersionKind]struct{})
|
||||
for i, w := range watches {
|
||||
if err := verifyGVK(w.GroupVersionKind); err != nil {
|
||||
return nil, fmt.Errorf("invalid GVK: %s: %w", w.GroupVersionKind, err)
|
||||
gvk := w.GroupVersionKind
|
||||
|
||||
if err := verifyGVK(gvk); err != nil {
|
||||
return nil, fmt.Errorf("invalid GVK: %s: %w", gvk, err)
|
||||
}
|
||||
|
||||
cl, err := loader.Load(w.ChartPath)
|
||||
@@ -66,31 +87,50 @@ func Load(path string) ([]Watch, error) {
|
||||
return nil, fmt.Errorf("invalid chart %s: %w", w.ChartPath, err)
|
||||
}
|
||||
w.Chart = cl
|
||||
w.OverrideValues = expandOverrideEnvs(w.OverrideValues)
|
||||
|
||||
if _, ok := watchesMap[gvk]; ok {
|
||||
return nil, fmt.Errorf("duplicate GVK: %s", gvk)
|
||||
}
|
||||
watchesMap[gvk] = struct{}{}
|
||||
|
||||
if w.WatchDependentResources == nil {
|
||||
trueVal := true
|
||||
w.WatchDependentResources = &trueVal
|
||||
}
|
||||
|
||||
if _, ok := watchesMap[w.GroupVersionKind]; ok {
|
||||
return nil, fmt.Errorf("duplicate GVK: %s", w.GroupVersionKind)
|
||||
if w.Selector == nil {
|
||||
w.Selector = &metav1.LabelSelector{}
|
||||
}
|
||||
|
||||
w.OverrideValues, err = expandOverrideValues(w.OverrideValues)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to expand override values")
|
||||
}
|
||||
|
||||
watchesMap[w.GroupVersionKind] = w
|
||||
watches[i] = w
|
||||
}
|
||||
return watches, nil
|
||||
}
|
||||
|
||||
func expandOverrideEnvs(in map[string]string) map[string]string {
|
||||
func expandOverrideValues(in map[string]string) (map[string]string, error) {
|
||||
if in == nil {
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
out := make(map[string]string)
|
||||
for k, v := range in {
|
||||
out[k] = os.ExpandEnv(v)
|
||||
envV := os.ExpandEnv(v)
|
||||
|
||||
v := &bytes.Buffer{}
|
||||
tmplV, err := template.New(k).Funcs(sprig.TxtFuncMap()).Parse(envV)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid template string %q: %v", envV, err)
|
||||
}
|
||||
if err := tmplV.Execute(v, nil); err != nil {
|
||||
return nil, fmt.Errorf("failed to execute template %q: %v", envV, err)
|
||||
}
|
||||
out[k] = v.String()
|
||||
}
|
||||
return out
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func verifyGVK(gvk schema.GroupVersionKind) error {
|
||||
|
||||
Reference in New Issue
Block a user