Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add new manifest deployer update strategies #624

Merged
merged 5 commits into from
Oct 25, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions apis/deployer/manifest/types_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ type ProviderConfiguration struct {
type UpdateStrategy string

const (
UpdateStrategyUpdate UpdateStrategy = "update"
UpdateStrategyPatch UpdateStrategy = "patch"
UpdateStrategyUpdate UpdateStrategy = "update"
UpdateStrategyPatch UpdateStrategy = "patch"
UpdateStrategyMerge UpdateStrategy = "merge"
UpdateStrategyMergeOverwrite UpdateStrategy = "mergeOverwrite"
)

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand Down
6 changes: 4 additions & 2 deletions apis/deployer/manifest/v1alpha2/types_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ type ProviderConfiguration struct {
type UpdateStrategy string

const (
UpdateStrategyUpdate UpdateStrategy = "update"
UpdateStrategyPatch UpdateStrategy = "patch"
UpdateStrategyUpdate UpdateStrategy = "update"
UpdateStrategyPatch UpdateStrategy = "patch"
UpdateStrategyMerge UpdateStrategy = "merge"
UpdateStrategyMergeOverwrite UpdateStrategy = "mergeOverwrite"
)

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand Down
10 changes: 9 additions & 1 deletion docs/deployer/manifest.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ spec:
apiVersion: manifest.deployer.landscaper.gardener.cloud/v1alpha2
kind: ProviderConfiguration

updateStrategy: update | patch # optional; defaults to update
updateStrategy: update | patch | merge | mergeOverwrite # optional; defaults to update

# Configuration of the readiness checks for the resources.
# optional
Expand Down Expand Up @@ -132,6 +132,14 @@ spec:
kind: Secret
jsonPath: ".data.somekey" # points to the value in the resource that is being exported
```
__Update Strategy__:

The update strategy defines the behavior of the manifest deployer when a resource for a rendered manifest already exists on the target cluster.

- `update`: The resources on the cluster will be updated with the results of the rendered manifests (default). Any changes to the resources, applied externally on the cluster, may be lost after the update.
- `patch`: The manifest deployer will calculate a JSON diff between the resources on the cluster and the rendered manifests. The diff will be applied as a patch. Any changes to the resources, applied externally on the cluster, may be lost after the update.
- `merge`: The manifest deployer will merge the results of the rendered manifests into the resources on the cluster. Fields that already exist in the resources on the cluster, will not be overwritten.
- `mergeOverwrite`: The manifest deployer will merge the results of the rendered manifests into the resources on the cluster. Fields that already exist in the resources on the cluster, will be overwritten when the rendered field is not empty.

__Policy__:

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ require (
github.com/golang/mock v1.6.0
github.com/google/uuid v1.3.0
github.com/hashicorp/go-multierror v1.1.1
github.com/imdario/mergo v0.3.12
github.com/mandelsoft/spiff v1.5.0
github.com/mandelsoft/vfs v0.0.0-20210530103237-5249dc39ce91
github.com/onsi/ginkgo v1.16.5
Expand Down Expand Up @@ -94,7 +95,6 @@ require (
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/huandu/xstrings v1.3.2 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jmoiron/sqlx v1.3.5 // indirect
github.com/josharian/intern v1.0.0 // indirect
Expand Down
60 changes: 45 additions & 15 deletions pkg/deployer/lib/resourcemanager/objectapplier.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"sync"
"time"

"github.com/imdario/mergo"

corev1 "k8s.io/api/core/v1"
extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -211,6 +213,7 @@ func (a *ManifestApplier) applyObject(ctx context.Context, manifest *Manifest) (
return nil, fmt.Errorf("unable to get object: %w", err)
}
// inject labels
a.injectLabels(obj)
kutil.SetMetaDataLabel(obj, manifestv1alpha2.ManagedDeployItemLabel, a.deployItemName)
if err := a.kubeClient.Create(ctx, obj); err != nil {
return nil, fmt.Errorf("unable to create resource %s: %w", key.String(), err)
Expand Down Expand Up @@ -238,24 +241,51 @@ func (a *ManifestApplier) applyObject(ctx context.Context, manifest *Manifest) (
return mr, nil
}

// inject manifest specific labels
a.injectLabels(obj)
kutil.SetMetaDataLabel(obj, manifestv1alpha2.ManagedDeployItemLabel, a.deployItemName)

// Set the required and immutable fields from the current object.
// Update fails if these fields are missing
if err := kutil.SetRequiredNestedFieldsFromObj(&currObj, obj); err != nil {
return mr, err
}

switch a.updateStrategy {
case manifestv1alpha2.UpdateStrategyUpdate:
if err := a.kubeClient.Update(ctx, obj); err != nil {
return mr, fmt.Errorf("unable to update resource %s: %w", key.String(), err)
}
fallthrough
case manifestv1alpha2.UpdateStrategyPatch:
if err := a.kubeClient.Patch(ctx, obj, client.MergeFrom(&currObj)); err != nil {
return mr, fmt.Errorf("unable to patch resource %s: %w", key.String(), err)
// inject manifest specific labels
a.injectLabels(obj)
kutil.SetMetaDataLabel(obj, manifestv1alpha2.ManagedDeployItemLabel, a.deployItemName)

// Set the required and immutable fields from the current object.
// Update fails if these fields are missing
if err := kutil.SetRequiredNestedFieldsFromObj(&currObj, obj); err != nil {
return mr, err
}

if a.updateStrategy == manifestv1alpha2.UpdateStrategyUpdate {
if err := a.kubeClient.Update(ctx, obj); err != nil {
return mr, fmt.Errorf("unable to update resource %s: %w", key.String(), err)
}
} else {
if err := a.kubeClient.Patch(ctx, obj, client.MergeFrom(&currObj)); err != nil {
return mr, fmt.Errorf("unable to patch resource %s: %w", key.String(), err)
}
}
case manifestv1alpha2.UpdateStrategyMerge:
fallthrough
case manifestv1alpha2.UpdateStrategyMergeOverwrite:
var mergeOpts []func(*mergo.Config)
if a.updateStrategy == manifestv1alpha2.UpdateStrategyMergeOverwrite {
mergeOpts = []func(*mergo.Config){
mergo.WithOverride,
}
} else {
mergeOpts = []func(*mergo.Config){}
}

if err := mergo.Merge(&currObj.Object, obj.Object, mergeOpts...); err != nil {
return mr, fmt.Errorf("unable to merge changes for resource %s: %w", key.String(), err)
}

// inject manifest specific labels
a.injectLabels(&currObj)
kutil.SetMetaDataLabel(&currObj, manifestv1alpha2.ManagedDeployItemLabel, a.deployItemName)

if err := a.kubeClient.Update(ctx, &currObj); err != nil {
return mr, fmt.Errorf("unable to update resource %s: %w", key.String(), err)
}
default:
return mr, fmt.Errorf("%s is not a valid update strategy", a.updateStrategy)
Expand Down
Loading